Find paths from one table to another over keys - sql

For example;
I have 500 tables in database. One table is named "Table1" and another "Table234". I need to join "Table1" and "Table234" but I can't join them directly, I need to use other tables. Is it possible to make query where I enter starting table (in this case Table1) and ending table (in this case Table234) and it finds all possible paths over keys from starting to ending table.
Let's say that I have two possible paths:
Table1 -> Table 23 -> Table456 -> Table234
Table1 -> Table 34 -> Table23 -> Zable 456 -> Table234
Select * from table1
join table23 on XX = XX
join table456 on XX = XX
join table234 on XX = XX
Maybe something like BFS to find shortest path, and than save it somewhere and find BFS without that path?
Solution (#Geoff Patterson):
IF OBJECT_ID('tempdb..#paths') IS NOT NULL
DROP TABLE #paths
IF OBJECT_ID('tempdb..#shortestPaths') IS NOT NULL
DROP TABLE #shortestPaths
GO
DECLARE #targetObjectName SYSNAME = 'YourTableNameHere'
;WITH singleColumnFkColumns AS (
SELECT fk1.*
FROM sys.foreign_key_columns fk1
LEFT JOIN sys.foreign_key_columns fk2 ON fk2.constraint_object_id = fk1.constraint_object_id AND fk2.constraint_column_id = 2
WHERE fk1.constraint_column_id = 1
AND fk2.constraint_object_id IS NULL
)
, parentCTE AS (
SELECT
p.object_id AS ParentId
,OBJECT_SCHEMA_NAME(p.object_id) + '.' + p.name AS ParentTable
,pc.column_id AS ParentColumnId
,pc.name AS ParentColumn
,r.object_id AS ChildId
,OBJECT_SCHEMA_NAME(r.object_id) + '.' + r.name AS ChildTable
,rc.column_id AS ChildColumnId
,rc.name AS ChildColumn
,1 AS depth
, ',' + CONVERT(VARCHAR(MAX), p.object_id) + '_NULL_' + CONVERT(VARCHAR(MAX), pc.column_id) +
',' + CONVERT(VARCHAR(MAX), r.object_id) + '_' + CONVERT(VARCHAR(MAX), pc.column_id) + '_' + CONVERT(VARCHAR(MAX), rc.column_id) AS TraversalPath
FROM sys.foreign_key_columns fk
JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id
JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id
JOIN sys.tables p ON p.object_id = fk.parent_object_id
JOIN sys.tables r ON r.object_id = fk.referenced_object_id
WHERE fk.parent_object_id = OBJECT_ID(#targetObjectName)
AND p.object_id <> r.object_id
UNION ALL
SELECT
p.object_id AS ParentId
,OBJECT_SCHEMA_NAME(p.object_id) + '.' + p.name AS ParentTable
,pc.column_id AS ParentColumnId
,pc.name AS ParentColumn
,r.object_id AS ChildId
,OBJECT_SCHEMA_NAME(r.object_id) + '.' + r.name AS ChildTable
,rc.column_id AS ChildColumnId
,rc.name AS ChildColumn
,cte.depth + 1 AS depth
,cte.TraversalPath + ',' + CONVERT(VARCHAR(MAX), r.object_id) + '_' + CONVERT(VARCHAR(MAX), pc.column_id) + '_' + CONVERT(VARCHAR(MAX), rc.column_id) AS TraversalPath
FROM parentCTE cte
JOIN singleColumnFkColumns fk
ON fk.parent_object_id = cte.ChildId
JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id
JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id
JOIN sys.tables p ON p.object_id = fk.parent_object_id
JOIN sys.tables r ON r.object_id = fk.referenced_object_id
WHERE p.object_id <> r.object_id
AND cte.TraversalPath NOT LIKE ('%_' + CONVERT(VARCHAR(MAX), r.object_id) + '%')
)
SELECT *
INTO #paths
FROM parentCTE
ORDER BY depth, ParentTable, ChildTable
GO
SELECT *
INTO #shortestPaths
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ChildTable ORDER BY depth ASC) AS rankToThisChild
FROM #paths
) x
WHERE rankToThisChild = 1
ORDER BY ChildTable
GO
WITH joinCTE AS (
SELECT p.ChildTable
, p.TraversalPath AS ParentTraversalPath
, NULL AS depth
, CONVERT(VARCHAR(MAX), 'FROM ' + p.ChildTable + ' t' + CONVERT(VARCHAR(MAX), p.depth+1)) AS JoinString
FROM #shortestPaths p
UNION ALL
SELECT cte.ChildTable
, REPLACE(p.TraversalPath, ',' + CONVERT(VARCHAR, p.ChildId) + '_' + CONVERT(VARCHAR, p.ParentColumnId)+ '_' + CONVERT(VARCHAR, p.ChildColumnId), '') AS TraversalPath
, p.depth
, cte.JoinString + '
' + CONVERT(VARCHAR(MAX), 'JOIN ' + p.ParentTable + ' t' + CONVERT(VARCHAR(MAX), p.depth) + ' ON t' + CONVERT(VARCHAR(MAX), p.depth) + '.' + p.ParentColumn + ' = t' + CONVERT(VARCHAR(MAX), p.depth+1) + '.' + p.ChildColumn) AS JoinString
FROM joinCTE cte
JOIN #paths p
ON p.TraversalPath = cte.ParentTraversalPath
)
SELECT ChildTable, 'SELECT TOP 100 *
' +JoinString
FROM joinCTE
WHERE depth = 1
ORDER BY ChildTable
GO
You can replace "YourTableNameHere" in script and it will find You all links to from any to that table.
And in my JAVA software looks like:
RS = CALIzb.main(Conn, "IF OBJECT_ID('tempdb..#paths') IS NOT NULL DROP TABLE #paths IF OBJECT_ID('tempdb..#shortestPaths') IS NOT NULL DROP TABLE #shortestPaths DECLARE #targetObjectName SYSNAME = '"+txtTablica.getText().trim()+"' ;WITH singleColumnFkColumns AS ( SELECT fk1.* FROM sys.foreign_key_columns fk1 LEFT JOIN sys.foreign_key_columns fk2 ON fk2.constraint_object_id = fk1.constraint_object_id AND fk2.constraint_column_id = 2 WHERE fk1.constraint_column_id = 1 AND fk2.constraint_object_id IS NULL ), parentCTE AS ( SELECT p.object_id AS ParentId ,OBJECT_SCHEMA_NAME(p.object_id) + '.' + p.name AS ParentTable,pc.column_id AS ParentColumnId,pc.name AS ParentColumn,r.object_id AS ChildId,OBJECT_SCHEMA_NAME(r.object_id) + '.' + r.name AS ChildTable,rc.column_id AS ChildColumnId,rc.name AS ChildColumn,1 AS depth, ',' + CONVERT(VARCHAR(MAX), p.object_id) + '_NULL_' + CONVERT(VARCHAR(MAX), pc.column_id) +',' + CONVERT(VARCHAR(MAX), r.object_id) + '_' + CONVERT(VARCHAR(MAX), pc.column_id) + '_' + CONVERT(VARCHAR(MAX), rc.column_id) AS TraversalPath FROM sys.foreign_key_columns fk JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id JOIN sys.tables p ON p.object_id = fk.parent_object_id JOIN sys.tables r ON r.object_id = fk.referenced_object_id WHERE fk.parent_object_id = OBJECT_ID(#targetObjectName) AND p.object_id <> r.object_id UNION ALL SELECT p.object_id AS ParentId,OBJECT_SCHEMA_NAME(p.object_id) + '.' + p.name AS ParentTable,pc.column_id AS ParentColumnId,pc.name AS ParentColumn,r.object_id AS ChildId,OBJECT_SCHEMA_NAME(r.object_id) + '.' + r.name AS ChildTable,rc.column_id AS ChildColumnId,rc.name AS ChildColumn,cte.depth + 1 AS depth,cte.TraversalPath + ',' + CONVERT(VARCHAR(MAX), r.object_id) + '_' + CONVERT(VARCHAR(MAX), pc.column_id) + '_' + CONVERT(VARCHAR(MAX), rc.column_id) AS TraversalPath FROM parentCTE cte JOIN singleColumnFkColumns fk ON fk.parent_object_id = cte.ChildId JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id JOIN sys.tables p ON p.object_id = fk.parent_object_id JOIN sys.tables r ON r.object_id = fk.referenced_object_id WHERE p.object_id <> r.object_id AND cte.TraversalPath NOT LIKE ('%_' + CONVERT(VARCHAR(MAX), r.object_id) + '%')) SELECT * INTO #paths FROM parentCTE ORDER BY depth, ParentTable, ChildTable SELECT * INTO #shortestPaths FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY ChildTable ORDER BY depth ASC) AS rankToThisChild FROM #paths) x WHERE rankToThisChild = 1 ORDER BY ChildTable");
RS = CALIzb.main(Conn, "WITH joinCTE AS ( SELECT p.ChildTable, p.TraversalPath AS ParentTraversalPath, NULL AS depth, CONVERT(VARCHAR(MAX), 'FROM ' + p.ChildTable + ' t' + CONVERT(VARCHAR(MAX), p.depth+1)) AS JoinString FROM #shortestPaths p UNION ALL SELECT cte.ChildTable, REPLACE(p.TraversalPath, ',' + CONVERT(VARCHAR, p.ChildId) + '_' + CONVERT(VARCHAR, p.ParentColumnId)+ '_' + CONVERT(VARCHAR, p.ChildColumnId), '') AS TraversalPath, p.depth, cte.JoinString + ' ' + CONVERT(VARCHAR(MAX), 'JOIN ' + p.ParentTable + ' t' + CONVERT(VARCHAR(MAX), p.depth) + ' ON t' + CONVERT(VARCHAR(MAX), p.depth) + '.' + p.ParentColumn + ' = t' + CONVERT(VARCHAR(MAX), p.depth+1) + '.' + p.ChildColumn) AS JoinString FROM joinCTE cte JOIN #paths p ON p.TraversalPath = cte.ParentTraversalPath) SELECT ChildTable, 'SELECT TOP 100 * ' +JoinString FROM joinCTE WHERE depth = 1 ORDER BY ChildTable");
vezaKljuceva.setModel(DbUtils.resultSetToTableModel(RS));

Related

Get specific columns from xml path

I have this query here:
SELECT
T.AKSIONERET,
sd.Identification_No, sd.Date_Of_Incorp,
sd.Ownership_Desc, sd.Ownership_Code,
sd.Subject_Name_Code, sd.Subject_Name,
sd.Subject_Type_Code,
LEFT(sd.Object_Desc, 3999) AS Object_Desc,
sd.Subject_Status_Name, sd.Subject_Name,
nr2.NACE_Code, nr2.NACE_PARENT, nr2.Description,
sd.Subject_Type_Name, sd.Subject_Status_Name,
sd.Subject_Type_Name, f.Place_Of_Registration, sd.Object_Desc
FROM
NRC_Subject_DEF AS sd
LEFT JOIN
NRC_Nace_REV2 AS nr2 ON nr2.Subject_DEF_Code = sd.Subject_DEF_Code
LEFT JOIN
NRC_ForeignCompany AS f ON sd.ForeignCompany_Code = f.ForeignCompany_Code
LEFT JOIN
(SELECT
SDP.Subject_DEF_Code,
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
FOR XML PATH('')) AS AKSIONERET
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T ON T.Subject_DEF_Code = SD.SUBJECT_DEF_CODE
I need to retrieve, instead of T.AKSIONERET the FullAksionerCitizenship which I get from the for xml path.
I know I have to do some other SELECT but I kept getting errors, syntax errors.
Could someone help?
Thanks in advance
I'm quite sure, that there could be a better design and I'm not able to run this against test data off course, but this could work:
SELECT
T.AKSIONERET,
T2.FullAksionerCitizenship,
sd.Identification_No, sd.Date_Of_Incorp,
sd.Ownership_Desc, sd.Ownership_Code,
sd.Subject_Name_Code, sd.Subject_Name,
sd.Subject_Type_Code,
LEFT(sd.Object_Desc, 3999) AS Object_Desc,
sd.Subject_Status_Name, sd.Subject_Name,
nr2.NACE_Code, nr2.NACE_PARENT, nr2.Description,
sd.Subject_Type_Name, sd.Subject_Status_Name,
sd.Subject_Type_Name, f.Place_Of_Registration, sd.Object_Desc
FROM
NRC_Subject_DEF AS sd
LEFT JOIN
NRC_Nace_REV2 AS nr2 ON nr2.Subject_DEF_Code = sd.Subject_DEF_Code
LEFT JOIN
NRC_ForeignCompany AS f ON sd.ForeignCompany_Code = f.ForeignCompany_Code
LEFT JOIN
(SELECT
SDP.Subject_DEF_Code,
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
FOR XML PATH('')) AS AKSIONERET
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T ON T.Subject_DEF_Code = SD.SUBJECT_DEF_CODE
--here starts the new block (difficult for me without knowing your db...)
LEFT JOIN
(SELECT
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
) AS FullAksionerCitizenship
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T2 ON T2.Subject_DEF_Code = SD.SUBJECT_DEF_CODE

Generate script of all indexes, keys in the SQL Server database

I am looking to generate scripts like:
ALTER TABLE dbo.Person
ADD CONSTRAINT PK_Person PRIMARY KEY CLUSTERED (PersonID);
CREATE INDEX IX_EVT_EVENTS on EVT_EVENTS(prg_event_t1, prg_event_t2, num_order)
The main problem I cannot find all information that I need, for example this query:
SELECT t.name TableName, I.*
FROM sys.indexes I
Inner Join sys.tables T on i.object_id=t.object_id
returns information about all keys and indexes, but.. there is no "Columns' Name" where can I get them?
I tried sys.all_columns and sys.key_constraints also.
Column names are stored in the sys.columns andsys.index_columns tables.
This will select the column names from all tables:
SELECT sc.name
FROM sys.tables st
INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
WHERE st.OBJECT_ID = 'ObjectID'
Or to join with the sys.indexes table, this will select the table name and the columns:
SELECT st.name ,
sc.name
FROM sys.indexes si
INNER JOIN sys.tables st ON si.object_id = st.object_id
INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
You can add a WHERE clause into the statement to filter on your index column
SELECT si.name ,
st.name ,
sc.name
FROM sys.indexes si
INNER JOIN sys.tables st ON si.object_id = st.object_id
INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
WHERE si.name = 'IX_EVT_EVENTS'
I have tried many scripts in web. All of them had flaws. I finally wrote my script using a post in msdn site and changed it to work on many kind of situations.
Note: This scripts works on SQL Server 2012 and later
WITH IndexInfo AS (
SELECT ix.object_id
, ix.NAME AS IndexName
, ix.type_desc
, ix.filter_definition
, ix.is_unique
, ix.is_primary_key
, ix.allow_row_locks
, ix.allow_page_locks
, ds.NAME AS DataSpaceName
, ds.type AS DataSpaceType
, ix.is_padded
, object_schema_name(ix.object_id) AS SchemaName
, object_name(ix.object_id) AS TableName
, IIF(ix.type <= 2, is_included_column, 0) AS HasIncludedColumn
, IIF(ix.type in (5, 6), 1, 0) AS IsColumnStore
, (
SELECT KeyColumns
FROM (
SELECT IC2.object_id
, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME + IIF(MAX(CONVERT(INT, IC1.is_descending_key)) = 1 AND ix.type <= 2, ' DESC ', ' ')
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 0
AND IIF(ix.type <= 2, IC1.is_included_column, 0) = 0
AND IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
GROUP BY IC1.object_id
, C.NAME
, index_id
, IC1.key_ordinal
, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') KeyColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id
, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
) AS KeyColumnsStr
, (
SELECT IncludedColumns
FROM (
SELECT IC2.object_id, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 1
AND IIF(ix.type <= 2, IC1.is_included_column, 0) <> 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
--and IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
GROUP BY IC1.object_id, C.NAME, index_id, IC1.key_ordinal, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') IncludedColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
AND IncludedColumns IS NOT NULL
) AS IncludedColumnsStr
FROM sys.indexes ix
INNER JOIN sys.index_columns ic ON ic.index_id = ix.index_id AND ic.object_id = ix.object_id
INNER JOIN sys.columns col ON col.column_id = ic.column_id AND col.object_id = ix.object_id
INNER JOIN sys.data_spaces ds ON ix.data_space_id = ds.data_space_id
WHERE ix.NAME IS NOT NULL AND IIF(ix.type <= 2, ic.key_ordinal, ic.index_column_id) > 0
)
, Scrpt AS (
SELECT *
, 'CREATE '
+ CASE WHEN is_unique = 1 THEN ' UNIQUE ' ELSE '' END
+ type_desc COLLATE DATABASE_DEFAULT + ' INDEX ' + IndexName + ' ON '
+ SchemaName + '.' + TableName + '(' + KeyColumnsStr + ')'
+ ISNULL(IIF(HasIncludedColumn > 0, ' ', ' INCLUDE (' + IncludedColumnsStr + ')'), '')
+ IIF(filter_definition IS NULL, ' ', ' WHERE ' + filter_definition)
+ ' WITH ('
+ CASE WHEN IsColumnStore = 1 THEN ' DROP_EXISTING = OFF '
ELSE
IIF(is_padded = 1, ' PAD_INDEX = ON ', ' PAD_INDEX = OFF ') + ','
+ ' DROP_EXISTING = OFF ' + ','
+ ' ONLINE = OFF ' + ','
+ IIF(allow_row_locks = 1, ' ALLOW_ROW_LOCKS = ON ', ' ALLOW_ROW_LOCKS = OFF ') + ','
+ IIF(allow_page_locks = 1, ' ALLOW_PAGE_LOCKS = ON ', ' ALLOW_PAGE_LOCKS = OFF ')
END
+ ' ) '
+ IIF(DataSpaceType = 'FG','ON [' + DataSpaceName + ']', '') AS CreateIndexScript
FROM IndexInfo
)
SELECT DISTINCT IndexName, CreateIndexScript
FROM Scrpt
WHERE object_id = object_id('dbo.SWPartition')
As a credit to original author, I mentions the original link here
How to Generate Index Creation Scripts

Dynamically create sql table from table list

I'm trying to create a bunch of tables in a schema base on a table list that pulls its table names from another schema
example
schA table1
schA table2
schA table3
dbo tablelist contains this tables in schema schA
so either i need to have some code that says
look at dbo tablelist verify it exists i
if not select table structure into schB from tables on database (where this doesn't exists)
my issue is the loop around
I'm not asking for someone to fully write this code (would be helpful though:-)
but how to structure my query or the best way to start
super thanks in advance
Possible this be helpful for you -
DDL:
CREATE TABLE [dbo].[test1](
[company_id] [int] NOT NULL PRIMARY KEY,
[staff_name] [nvarchar](50) NULL,
[email] [nvarchar](50) NULL
) ON [PRIMARY]
Query:
DECLARE
#table_name SYSNAME
, #name_for_new_table SYSNAME
, #schema_for_new_table SYSNAME
SELECT
#table_name = 'dbo.test1'
, #schema_for_new_table = 'dbo'
, #name_for_new_table = 'test1_new'
DECLARE #SQL NVARCHAR(MAX) = ''
;WITH tbl AS
(
SELECT o.[object_id]
FROM sys.objects o WITH (NOWAIT)
WHERE SCHEMA_NAME(o.[schema_id]) + '.' + o.name = #table_name
AND o.[type] = 'U'
AND o.is_ms_shipped = 0
),
index_column AS
(
SELECT
ic.[object_id]
, ic.index_id
, ic.is_descending_key
, ic.is_included_column
, c.name
FROM sys.index_columns ic WITH (NOWAIT)
JOIN sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
WHERE ic.[object_id] IN (SELECT t.[object_id] FROM tbl t)
),
fk_columns AS
(
SELECT
k.constraint_object_id
, cname = c.name
, rcname = rc.name
FROM sys.foreign_key_columns k WITH (NOWAIT)
JOIN sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id
JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
)
SELECT #SQL = 'CREATE TABLE [' + #schema_for_new_table + '].[' + #name_for_new_table + ']' + CHAR(13) + '(' + CHAR(13) + STUFF((
SELECT DISTINCT CHAR(9) + ', [' + c.name + '] ' + UPPER(t.name) +
CASE WHEN t.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
THEN '(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length AS NVARCHAR(5)) END + ')'
WHEN t.name IN ('nvarchar', 'nchar', 'ntext')
THEN '(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length / 2 AS NVARCHAR(5)) END + ')'
WHEN t.name IN ('datetime2', 'time2', 'datetimeoffset')
THEN '(' + CAST(c.scale AS NVARCHAR(5)) + ')'
WHEN t.name = 'decimal'
THEN '(' + CAST(c.[precision] AS NVARCHAR(5)) + ',' + CAST(c.scale AS NVARCHAR(5)) + ')'
ELSE ''
END +
CASE WHEN c.collation_name IS NOT NULL THEN ' COLLATE ' + c.collation_name ELSE '' END +
CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END +
CASE WHEN c.[definition] IS NOT NULL THEN ' DEFAULT' + c.[definition] ELSE '' END +
CASE WHEN c.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(c.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(c.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END + CHAR(13)
FROM (
SELECT
c.name
, c.user_type_id
, c.max_length
, c.[precision]
, c.scale
, dc.[definition]
, ic.seed_value
, ic.increment_value
, c.collation_name
, c.is_nullable
, c.is_identity
FROM sys.columns c WITH (NOWAIT)
LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id
LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
WHERE c.[object_id] IN (SELECT o.[object_id] FROM tbl o)
) c
JOIN sys.types t WITH (NOWAIT) ON c.user_type_id = t.user_type_id
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
+ ISNULL((SELECT CHAR(9) + ', CONSTRAINT [PK_' + #schema_for_new_table + '_' + #name_for_new_table + '] PRIMARY KEY (' +
(SELECT STUFF((
SELECT DISTINCT ', [' + c.name + ']' + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
FROM sys.key_constraints k WITH (NOWAIT)
JOIN sys.index_columns ic WITH (NOWAIT) ON ic.[object_id] = k.parent_object_id AND ic.index_id = k.unique_index_id
JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = ic.column_id
WHERE k.[type] = 'PK'
AND ic.is_included_column = 0
AND k.parent_object_id IN (SELECT t.[object_id] FROM tbl t)
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')) + ')' + CHAR(13)), '')
+ ')' + CHAR(13)
+ ISNULL((SELECT (
SELECT CHAR(13) +
'ALTER TABLE [' + #schema_for_new_table + '].[' + #name_for_new_table + '] WITH'
+ CASE WHEN fk.is_not_trusted = 1
THEN ' NOCHECK'
ELSE ' CHECK'
END +
' ADD CONSTRAINT [FK_' + #schema_for_new_table + '_' + #name_for_new_table + '_' + fk.name + '] FOREIGN KEY('
+ STUFF((
SELECT ', [' + k.cname + ']'
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')
+ ')' +
' REFERENCES [' + SCHEMA_NAME(ro.[schema_id]) + '].[' + ro.name + '] ('
+ STUFF((
SELECT ', [' + k.rcname + ']'
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')
+ ')'
+ CASE
WHEN fk.delete_referential_action = 1 THEN ' ON DELETE CASCADE'
WHEN fk.delete_referential_action = 2 THEN ' ON DELETE SET NULL'
WHEN fk.delete_referential_action = 3 THEN ' ON DELETE SET DEFAULT'
ELSE ''
END
+ CASE
WHEN fk.update_referential_action = 1 THEN ' ON UPDATE CASCADE'
WHEN fk.update_referential_action = 2 THEN ' ON UPDATE SET NULL'
WHEN fk.update_referential_action = 3 THEN ' ON UPDATE SET DEFAULT'
ELSE ''
END
+ CHAR(13) + 'ALTER TABLE [' + #schema_for_new_table + '].[' + #name_for_new_table + '] CHECK CONSTRAINT [FK_' + #schema_for_new_table + '_' + #name_for_new_table + '_' + fk.name + ']' + CHAR(13)
FROM sys.foreign_keys fk WITH (NOWAIT)
JOIN sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
WHERE fk.parent_object_id IN (SELECT t.[object_id] FROM tbl t)
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)')), '')
+ ISNULL(((SELECT
CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END + ' NONCLUSTERED INDEX [IX_' + #schema_for_new_table + '_' + #name_for_new_table + '_' + i.name + '] ON [' + #schema_for_new_table + '].[' + #name_for_new_table + '] (' +
STUFF((
SELECT ', [' + c.name + ']' + CASE WHEN c.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
FROM index_column c
WHERE c.is_included_column = 0
AND c.index_id = i.index_id
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '') + ')'
+ ISNULL(CHAR(13) + 'INCLUDE (' +
STUFF((
SELECT ', [' + c.name + ']'
FROM index_column c
WHERE c.is_included_column = 1
AND c.index_id = i.index_id
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '') + CHAR(13)
FROM sys.indexes i WITH (NOWAIT)
WHERE i.[object_id] IN (SELECT t.[object_id] FROM tbl t)
AND i.is_primary_key = 0
AND i.[type] = 2
FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)')
), '')
PRINT #SQL
--EXEC sys.sp_executesql #SQL
Output:
CREATE TABLE [dbo].[test1_new]
(
[company_id] INT NOT NULL
, [email] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, [staff_name] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, CONSTRAINT [PK_dbo_test1_new] PRIMARY KEY ([company_id] ASC)
)

dynamic sql query with FOR XML Path

I have following sql and when i run this its throw error
Incorrect syntax near '1'.
declare #sql nvarchar(max)
set #sql =N'SELECT PT.P_Name as Prisoner_Type,
PE.PID_No,PE.Jail_Code,PE.Entry_Year,Convert(varchar(10),PE.Admission_Date,103) Admission_Date,PE.JID_No,Convert(varchar(10),PE.Release_Date,103) Release_Date ,
PM.Prisoner_Name, SUBSTRING(PM.Father_Name, 0, 17)as Father_Name, PM.Mother_Name,PM.Spouse_Name,PM.Caste_Code,
PM.Religion_Code,PM.Occupation_Code,PM.Qualification,PM.Tendency_Type,PM.Risk_Type,PM.Annual_Income_Code,PM.Marital_Status_Code,PM.Id_Mark,
PM.Sex_Code,PM.Nationality_Code,PM.Off_Code,PM.Present_Add, Age as age ,PM.Permt_Add, LS.Location AS Location
,NT.Nation_Name , JT.Jail_Address
,OT.Offence_Name,QT.Qualification as quali ,IT.Annual_Income_Range,CT.Caste_Name
,RT.Religion_Name,MT.Marital_Status_Name,OFT.Occ_Name AS Occupation
, STUFF(( SELECT '', '' + cc.Act_Sec AS [text()]
FROM CourtCases cc
WHERE
cc.PID_NO = PE.PID_NO and ('','' + Replace(pe.Case_No,''$'','','') +'','' LIKE ''%,'' + CONVERT(VARCHAR, cc.Case_No) + '',%'') group by cc.Act_Sec
FOR XML PATH('''') ),'+ cast(1 as nvarchar(10))+', '+cast(1 as nvarchar(10))+', '''' )
AS [Act_Sec]
, STUFF(( SELECT '', '' + Convert(varchar(10),CC.Fir_Date,103) AS [text()]
FROM CourtCases cc
WHERE
cc.PID_NO = PE.PID_NO and ('','' + Replace(pe.Case_No,''$'','','') +'','' LIKE ''%,'' + CONVERT(VARCHAR, cc.Case_No) + '',%'') group by Convert(varchar(10),CC.Fir_Date,103)
FOR XML PATH('''') ),'+ cast(1 as nvarchar(10))+', '+cast(1 as nvarchar(10))+', '''' )
AS [Fir_Date]
,STUFF(( SELECT '', '' + FIR_No AS [text()]
FROM CourtCases cc
WHERE
cc.PID_NO = PE.PID_NO and ('','' + Replace(pe.Case_No,''$'','','') +'','' LIKE ''%,'' + CONVERT(VARCHAR, cc.Case_No) + '',%'') group by FIR_No
FOR XML PATH('''') ),'+ cast(1 as nvarchar(10))+', '+cast(1 as nvarchar(10))+', '''' )
AS [FIR_No]
, STUFF(( SELECT '', '' + ct.Court_Name AS [text()]
FROM CourtCases cc inner join Court_Tab as ct
ON cc.Court_Code=convert(nvarchar(50),ct.Court_Code)
WHERE
cc.PID_NO = PE.PID_NO and ('','' + Replace(pe.Case_No,''$'','','') +'','' LIKE ''%,'' + CONVERT(VARCHAR, cc.Case_No) + '',%'') group by ct.Court_Name
FOR XML PATH('''') ),'+ cast(1 as nvarchar(10))+', '+cast(1 as nvarchar(10))+', '''' )
AS [Court_Name]
, STUFF(( SELECT '', '' + pt.PS_Name AS [text()]
FROM CourtCases cc inner join PS_Tab as pt
ON convert(nvarchar(50),cc.PS_Code)=convert(nvarchar(50),pt.PS_Code)
WHERE
cc.PID_NO = PE.PID_NO and ('','' + Replace(pe.Case_No,''$'','','') +'','' LIKE ''%,'' + CONVERT(VARCHAR, cc.Case_No) + '',%'') group by pt.PS_Name
FOR XML PATH('''') ),'+ cast(1 as nvarchar(10))+', '+cast(1 as nvarchar(10))+', '''' )
AS [PS_Name]
FROM PrisonMaster AS PM
INNER JOIN PrisonerEntry AS PE ON PE.PID_No = PM.PID_No AND PE.Jail_Code='+cast(#JailCode as nvarchar) +
'INNER JOIN Nation_Tab AS NT ON PM.Nationality_Code = NT.Nation_Code
INNER JOIN Sex_Tab AS S ON PM.Sex_Code = S.Sex_Code
INNER JOIN Jail_Tab AS JT ON PE.Jail_Code = JT.Jail_Code
INNER JOIN Prisoner_Tab AS PT ON PE.Prisoner_Type=PT.P_Type
INNER JOIN Loc_Status AS LS ON PE.Location=LS.Loc_Status
left JOIN Offence_Tab AS OT ON OT.Offence_Code=PM.Occupation_Code
left JOIN Qualification_Tab AS QT ON QT.Q_Code=PM.Qualification
left JOIN Income_Tab AS IT ON IT.Annual_Income_Code=PM.Annual_Income_Code
left JOIN Caste_Tab AS CT ON CT.Caste_Code=PM.Caste_Code
LEFT JOIN Religion_Tab AS RT ON RT.Religion_Code=PM.Religion_Code
LEFT JOIN Marital_Tab AS MT ON MT.Marital_Status_Code=PM.Marital_Status_Code
LEFT JOIN Occupation_Tab AS OFT ON OFT.Occ_Code=PM.Occupation_Code
WHERE
PE.Admission_Date BETWEEN '+cast(#DATE1 as nvarchar(50))+' and '+ cast(#DATE2 as nvarchar(50))
exec (#sql)
What the ... is this + cast(1 as nvarchar(10))+ ?
Just do + '1' + or even better just add the 1 into your string.

Generating create table script (with indexes, keys, constrains) for all tables in SQL Server database

If I run the following script
SELECT so.Name, sc.Text
FROM syscomments sc JOIN sysobjects so ON sc.ID = so.ID
I will get all the create procedure/function scripts. Is there something like this for tables, indexes, keys, and triggers?
Thank you for your help!
Nothing inbuilt.
To do it in T-SQL You'd need to find or write your own script. Example here that might get you started.
for SQL 2012 and later use this
I have tried many scripts in web. All of them had flaws. I finally wrote my script using a post in msdn site and changed it to work on many kind of situations.
Note: This scripts works on SQL Server 2012 and later
WITH IndexInfo AS (
SELECT ix.object_id
, ix.NAME AS IndexName
, ix.type_desc
, ix.filter_definition
, ix.is_unique
, ix.is_primary_key
, ix.allow_row_locks
, ix.allow_page_locks
, ds.NAME AS DataSpaceName
, ds.type AS DataSpaceType
, ix.is_padded
, object_schema_name(ix.object_id) AS SchemaName
, object_name(ix.object_id) AS TableName
, IIF(ix.type <= 2, is_included_column, 0) AS HasIncludedColumn
, IIF(ix.type in (5, 6), 1, 0) AS IsColumnStore
, (
SELECT KeyColumns
FROM (
SELECT IC2.object_id
, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME + IIF(MAX(CONVERT(INT, IC1.is_descending_key)) = 1 AND ix.type <= 2, ' DESC ', ' ')
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 0
AND IIF(ix.type <= 2, IC1.is_included_column, 0) = 0
AND IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
GROUP BY IC1.object_id
, C.NAME
, index_id
, IC1.key_ordinal
, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') KeyColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id
, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
) AS KeyColumnsStr
, (
SELECT IncludedColumns
FROM (
SELECT IC2.object_id, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 1
AND IIF(ix.type <= 2, IC1.is_included_column, 0) <> 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
--and IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
GROUP BY IC1.object_id, C.NAME, index_id, IC1.key_ordinal, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') IncludedColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
AND IncludedColumns IS NOT NULL
) AS IncludedColumnsStr
FROM sys.indexes ix
INNER JOIN sys.index_columns ic ON ic.index_id = ix.index_id AND ic.object_id = ix.object_id
INNER JOIN sys.columns col ON col.column_id = ic.column_id AND col.object_id = ix.object_id
INNER JOIN sys.data_spaces ds ON ix.data_space_id = ds.data_space_id
WHERE ix.NAME IS NOT NULL AND IIF(ix.type <= 2, ic.key_ordinal, ic.index_column_id) > 0
)
, Scrpt AS (
SELECT *
, 'CREATE '
+ CASE WHEN is_unique = 1 THEN ' UNIQUE ' ELSE '' END
+ type_desc COLLATE DATABASE_DEFAULT + ' INDEX ' + IndexName + ' ON '
+ SchemaName + '.' + TableName + '(' + KeyColumnsStr + ')'
+ ISNULL(IIF(HasIncludedColumn > 0, ' ', ' INCLUDE (' + IncludedColumnsStr + ')'), '')
+ IIF(filter_definition IS NULL, ' ', ' WHERE ' + filter_definition)
+ ' WITH ('
+ CASE WHEN IsColumnStore = 1 THEN ' DROP_EXISTING = OFF '
ELSE
IIF(is_padded = 1, ' PAD_INDEX = ON ', ' PAD_INDEX = OFF ') + ','
+ ' DROP_EXISTING = OFF ' + ','
+ ' ONLINE = OFF ' + ','
+ IIF(allow_row_locks = 1, ' ALLOW_ROW_LOCKS = ON ', ' ALLOW_ROW_LOCKS = OFF ') + ','
+ IIF(allow_page_locks = 1, ' ALLOW_PAGE_LOCKS = ON ', ' ALLOW_PAGE_LOCKS = OFF ')
END
+ ' ) '
+ IIF(DataSpaceType = 'FG','ON [' + DataSpaceName + ']', '') AS CreateIndexScript
FROM IndexInfo
)
SELECT DISTINCT IndexName, CreateIndexScript
FROM Scrpt
WHERE object_id = object_id('dbo.SWPartition')
As a credit to original author, I mentions the original link here
How to Generate Index Creation Scripts