SQL Server view metadata information - sql-server

I have a table as below:
create table employee_details
(
id int,
name varchar(10)
)
And this is a view based on employee_details:
create view vw_empl_details
as
select id as emp_id, name as emp_name
from employee_details
I want to know which system table keeps track of column wise information for above condition..
id-> emp_id
name-> emp_name
we have below 2 tables to keep track of tables but not sure columnwise information is available in SQL Server
select * from [INFORMATION_SCHEMA].[VIEW_COLUMN_USAGE]
select * from [INFORMATION_SCHEMA].VIEW_TABLE_USAGE

I guess you want (sys.sql_modules.definition):
SELECT *
FROM sys.sql_modules
WHERE OBJECT_ID = OBJECT_ID('vw_empl_details');
Rextester.com
Mapping only when there is simple aliasing:
SELECT column_ordinal, name, source_table, source_column
FROM sys.dm_exec_describe_first_result_set
('SELECT * FROM vw_empl_details', NULL, 1);
Output:
Rextester Demo2

Related

How to store complete Stored_Procedure content in a table as a record in sql server?

I am working on SSIS, through which I have to copy the complete Stored procedure from one SQL server instance to another instance in a table as a record. How can I achieve that? For eg:
-----sp------
Create PROCEDURE simplesp
AS
SELECT * FROM sample
GO;
-------table----------
select ID,SP_info from SP_Content;
the above table query should return a value like,
ID SP_info
---- ------------------------------------------------------
1 Create PROCEDURE simplesp AS SELECT * FROM sample GO;
You might be looking for something like this.
SELECT row_number() OVER (ORDER BY OBJECT_NAME(OBJECT_ID)) ID,
OBJECT_NAME(OBJECT_ID) as Name,
definition as SP_info
FROM sys.sql_modules
WHERE
objectproperty(OBJECT_ID, 'IsProcedure') = 1

Refresh View after table drop

I have the following tables:
Series One Tables:
create table tbl1
(
id int,
name varchar(100)
);
insert into tbl1 values(1,'tbl1');
create table tbl2
(
id int,
name varchar(100)
);
insert into tbl2 values(1,'tbl2');
create table tbl3
(
id int,
name varchar(100)
);
insert into tbl3 values(1,'tbl3');
create table tbl4
(
id int,
name varchar(100)
);
insert into tbl4 values(1,'tbl4');
Series Double Tables:
create table tbl11
(
id int,
name varchar(100)
);
insert into tbl11 values(1,'tbl11');
create table tbl22
(
id int,
name varchar(100)
);
insert into tbl22 values(1,'tb22');
create table tbl33
(
id int,
name varchar(100)
);
insert into tbl33 values(1,'tbl33');
create table tbl44
(
id int,
name varchar(100)
);
insert into tbl44 values(1,'tbl44');
Now I want to create VIEW of each series tables:
Series One View:
create view View_tbl_one_series as
select * from tbl1
union all
select * from tbl2
union all
select * from tbl3
union all
select * from tbl4
Series Double View:
create view View_tbl_double_series as
select * from tbl11
union all
select * from tbl22
union all
select * from tbl33
union all
select * from tbl44
After that I DROP TABLE tbl1 for some reason and creating another VIEW which contains the definition of two series views.
VIEW ALL:
create view All_VIEW AS
select * from View_tbl_one_series
union all
select * from View_tbl_double_series
Getting an error:
Msg 208, Level 16, State 1, Procedure View_tbl_one_series, Line 2
Invalid object name 'tbl1'.
Try:
exec sp_refreshview View_tbl_one_series
but still getting same error.
Note: I have many tables and views in the database system, and creating view all is the last procedure, and between that have to drop some tables for some reason.
A non materialized view in SQL Server can be thought of as just a thin wrapper on top of the underlying tables which appear in that view. If you drop one or more of the tables involved in the view, it won't work, because the table can no longer be queried. There are a number of workarounds here, one of which would be to just create an indexed (materialized) view:
CREATE VIEW View_tbl_one_series
WITH SCHEMABINDING
AS
SELECT * from tbl1
UNION ALL
SELECT * from tbl2
UNION ALL
SELECT * from tbl3
UNION ALL
SELECT * from tbl4
GO
CREATE UNIQUE CLUSTERED INDEX idx ON View_tbl_one_series (id);
Other options would include using a temporary table for the same purpose, or maybe even a bona fide regular table.
Note that in general doing SELECT * in a union query is not ideal, because it leaves open the possibility that the columns/column types may not line up properly between the two tables involved in the union.

Can I use dynamically LIKE and IN together?

I want to be able to say :
SELECT * FROM myTable WHERE accountName LIKE('%john%', '%bill%', '%lory%'.....)
I want that to be dynamically, which means depend on user input the list of '%name%' parts will be different. One time could have 3 names and another probably just 1.
You could use JOIN:
SELECT DISTINCT myTable.*
FROM myTable
JOIN (SELECT '%john%' UNION ALL
SELECT '%bill%' UNION ALL
SELECT '%lory%') sub(c) -- this could be anything table variable/temp
ON myTable.accountName LIKE sub.c;
Keep in mind that '%...%' is not SARG-able.
With table variable:
DECLARE #tab AS TABLE (c NVARCHAR(100));
INSERT INTO #tab(c) VALUES ('...');
-- ...
SELECT DISTINCT myTable.*
FROM myTable
JOIN #tab t
ON myTable.accountName LIKE t.c;
WHERE accountName LIKE('%john%', '%bill%', '%lory%'.....)
This is invalid syntax and won't work. The easiest way to do what you're trying to do would be to use a "string splitter" function like Jeff Moden's DelimitedSplit8K
DECLARE #Names VARCHAR(1000) = 'john, bill, lory';
SELECT
*
FROM
dbo.myTable mt
CROSS APPLY dbo.DelimitedSplit8K(#Names, ',') dsk
WHERE
mt.accountname LIKE '%' + dsk.Item + '%';
OR
SELECT
*
FROM
dbo.myTable mt
WHERE
EXISTS (
SELECT 1
FROM dbo.DelimitedSplit8K(#Names, ',') dsk
WHERE mt.accountname LIKE '%' + dsk.Item + '%'
);
HTH, Jason
Building off of Jason and Lad's very excellent solutions you could speed things up with an indexed view.
Before I continue - it's important to note that this will slow down inserts/updates/deletes in high-traffic OLTP environments that modify these tables often. TEST, TEST, TEST!.
I work in the Data Warehouse world where this works out quite nicely.
First a keyword table for common search terms:
CREATE TABLE dbo.keyword (kw varchar(100) not null, constraint uq_keyword unique clustered(kw));
INSERT dbo.keyword VALUES ('john'), ('bill'), ('lory');
Next for your table:
CREATE TABLE dbo.mytable(someid int identity not null, accountname varchar(100));
INSERT dbo.mytable(accountname) VALUES
('John''s Flowers'), ('Candles by Bill'), ('Some other account'), ('The Lory Group LLC');
Now the view along with a couple important indexes:
CREATE VIEW dbo.vw_mytable_fastKWLookup
WITH SCHEMABINDING AS -- schemabinding required for indexed views
SELECT
t.someid,
t.accountname,
k.kw
FROM dbo.mytable t
CROSS JOIN dbo.keyword k
WHERE t.accountname LIKE '%'+k.kw+'%';
GO
-- required unique clustered index
CREATE UNIQUE CLUSTERED INDEX uq_cl_vw_mytable_fastKWLookup
ON dbo.vw_mytable_fastKWLookup(kw, someid);
-- A good nonclustered index
CREATE NONCLUSTERED INDEX nc_vw_mytable_fastKWLookup__kw
ON dbo.vw_mytable_fastKWLookup(kw) include (someid, accountname);
Once your indexed view is in place you can add your search words to an in list like so:
SELECT someid, accountname, kw
FROM vw_mytable_fastKWLookup WITH (NOEXPAND)
WHERE kw IN ('John', 'Lory', 'Bill', 'Fred');
Results:
someid accountname kw
----------- -------------------- -----
1 John's Flowers john
2 Candles by Bill bill
4 The Lory Group LLC lory
The reward here is an execution plan that does a non-clustered index seek for %searchstring% style searches.

SQL Server : openquery insert linked server

How do I insert data into a linked server (oracle) with a condition that a row does not exist?
I want to insert into employee table if employeecode does not exist yet in that table
INSERT INTO OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') -- I want a where clause here
Select EID, ENAME FROM EMPDATA
You might actually have to read from the table twice
INSERT INTO OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') -- I want a where clause here
Select D.EID, D.ENAME
FROM EMPDATA D
LEFT JOIN OPENQUERY(ORACLEX,
'SELECT EMPCODE, EMPNAME FROM AX.EMPLOYEE') OQ ON OQ.EMPCODE = D.EID
WHERE QQ.EMPCODE IS NULL;

SELECT INSERT INTO

Is it possible to insert data from select statement into a a dynamically created table? I will not know how many columns are there in select statement until I run the query. It has to create the appropriate number of columns at run time.
Thank you,
Smith
Just use the SELECT INTO syntax:
SELECT *
INTO NewTable
FROM MyTable
WHERE ...
The new table NewTable will be created with the same columns as your select statement.
You can use a CTAS pattern for this
USE AdventureWorks
GO
----Create new table and insert into table using SELECT INSERT
SELECT FirstName, LastName
INTO TestTable
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable
GO
Have a look at This Article on CTAS
-- This creates temporary table
select *
into #newtable
from YourTable
select * from #newtable
-- This creates physical table in the DB
select *
into newtable
from YourTable
select * from newtable

Resources