SQL Server / T-SQL need to modify dynamic stored procedure? - sql

I have a stored procedure that dynamically generates MERGE TSQL statements to handle SCD Type 1 updates between the given Dimension / Staging table dump.
Here is the T-SQL code (modified from the original code by Alex Whittles):
USE [OPPY_DWUSD]
GO
ALTER PROCEDURE [dbo].[GenerateMerge]
/***************************************************************
* *
* Script for use with blog post *
* "Automating T-SQL Merge to load Dimensions (SCD)" *
* http://www.purplefrogsystems.com/blog/2012/04/automating-t-sql-merge-to-load-dimensions-scd
* *
* Posted: 6th April 2012 *
* *
* By: Alex Whittles - Purple Frog Business Intelligence *
* www.PurpleFrogSystems.com *
* *
* All code samples are provided “AS IS” without warranty of *
* any kind, either express or implied, including but not *
* limited to the implied warranties of merchantability *
* and/or fitness for a particular purpose. *
* *
***************************************************************/
#Dimension varchar(50),
#Schema varchar(50),
#ETLTable varchar(50),
#ETLSchema varchar(50),
#Execute bit=0 --Should the resulting merge be returned or executed
AS
BEGIN
SET NOCOUNT ON;
--Create Carriage return variable to format the resulting query
DECLARE #crlf char(2)
SET #crlf = CHAR(13)
--Find out which Audit fields are used
DECLARE #UseIsInferred bit
DECLARE #UseFirstCreated bit
DECLARE #UseValidTo bit
DECLARE #UseIsRowCurrent bit
DECLARE #UseLastUpdated bit
SET #UseIsInferred = ISNULL((SELECT MAX(1)
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name = 'IsInferred'
),0)
SET #UseFirstCreated= ISNULL((SELECT MAX(1)
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name = 'FirstCreated'
),0)
SET #UseValidTo = ISNULL((SELECT MAX(1)
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name = 'ValidTo'
),0)
SET #UseIsRowCurrent = ISNULL((SELECT MAX(1)
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name = 'IsRowCurrent'
),0)
SET #UseLastUpdated = ISNULL((SELECT MAX(1)
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name = 'LastUpdated'
),0)
--Identify the business key column(s)
--Also define what the null replacement should be
DECLARE myCurBK Cursor FOR
SELECT c.name
, CASE WHEN ty.name IN ('text', 'ntext', 'varchar', 'char', 'nvarchar', 'nchar') THEN ''''''
WHEN ty.name IN ('tinyint', 'smallint', 'int', 'real', 'money', 'float', 'bit', 'decimal', 'numeric','smallmoney','bigint') THEN '0'
WHEN ty.name IN ('date', 'datetime') THEN '''19000101'''
ELSE 'NULL' END AS NullRep
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
INNER JOIN sys.extended_properties ep
ON t.object_id=ep.major_id
AND c.column_id=ep.minor_id
AND ep.class=1
AND ep.name='SCD'
WHERE s.name = #Schema
AND t.name = #Dimension
AND ep.value = 'BK'
ORDER BY c.column_id
--Identify all fields to be merged (Exclude Type 0)
DECLARE myCurType1 Cursor
FOR SELECT c.name
, CASE WHEN ty.name IN ('text', 'ntext', 'varchar', 'char', 'nvarchar', 'nchar') THEN ''''''
WHEN ty.name IN ('tinyint', 'smallint', 'int', 'real', 'money', 'float', 'bit', 'decimal', 'numeric','smallmoney','bigint') THEN '0'
WHEN ty.name IN ('date', 'datetime') THEN '''19000101'''
ELSE 'NULL' END AS NullRep
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
LEFT JOIN sys.extended_properties ep
ON t.object_id=ep.major_id
AND c.column_id=ep.minor_id
AND ep.class=1
AND ep.name='SCD'
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.is_identity=0
AND ISNULL(ep.value,'1') NOT IN ('0', 'Audit', 'BK')
ORDER BY c.column_id ASC
--Identify all fields for insert
DECLARE myCurAll Cursor
FOR SELECT c.name
, CASE WHEN ty.name IN ('text', 'ntext', 'varchar', 'char', 'nvarchar', 'nchar') THEN ''''''
WHEN ty.name IN ('tinyint', 'smallint', 'int', 'real', 'money', 'float', 'bit', 'decimal', 'numeric','smallmoney','bigint') THEN '0'
WHEN ty.name IN ('date', 'datetime') THEN '''19000101'''
ELSE 'NULL' END AS NullRep
FROM sys.columns c
INNER JOIN sys.tables t on c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE s.name = #Schema
AND t.name = #Dimension
AND c.name NOT IN ('LastUpdated', 'IsInferred', 'FirstCreated', 'ValidTo', 'IsRowCurrent')
AND c.is_identity=0
ORDER BY c.column_id ASC
DECLARE #Field varchar(255)
DECLARE #NullRep varchar(20)
DECLARE #SQL varchar(max)
DECLARE #SQL2 varchar(max)
DECLARE #SQL3 varchar(max)
--Now start building up the dynamic SQL
SET #SQL ='MERGE [' + #Schema + '].[' + #Dimension + '] AS Target'
SET #SQL = #SQL + #crlf + 'USING [' + #ETLSchema + '].[' + #ETLTable + '] AS Source'
OPEN myCurBK
FETCH NEXT FROM myCurBK INTO #Field, #NullRep
IF (##FETCH_STATUS>=0)
BEGIN
SET #SQL = #SQL + #crlf + ' ON Target.' + '[' + #Field + ']' + ' = Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurBK INTO #Field, #NullRep
END
WHILE (##FETCH_STATUS<>-1)
BEGIN
IF (##FETCH_STATUS<>-2)
SET #SQL = #SQL + #crlf + ' AND Target.' + '[' + #Field + ']' + ' = Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurBK INTO #Field, #NullRep
END
CLOSE myCurBK
IF #UseIsRowCurrent>0 SET #SQL = #SQL + #crlf + ' AND Target.IsRowCurrent=1'
SET #SQL = #SQL + #crlf + ' WHEN MATCHED'
OPEN myCurType1
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
IF (##FETCH_STATUS>=0)
BEGIN
SET #SQL = #SQL + #crlf + ' AND (ISNULL(Target.' + '[' + #Field + ']' + ',' + #NullRep + ') <> ISNULL(Source.' + '[' + #Field + ']' + ',' + #NullRep + ')'
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
END
WHILE (##FETCH_STATUS<>-1)
BEGIN
IF (##FETCH_STATUS<>-2)
SET #SQL = #SQL + #crlf + ' OR ISNULL(Target.' + '[' + #Field + ']' + ',' + #NullRep + ') <> ISNULL(Source.' + '[' + #Field + ']' + ',' + #NullRep + ')'
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
END
CLOSE myCurType1
SET #SQL = #SQL + #crlf + ' )'
SET #SQL2 = ' THEN UPDATE SET'
OPEN myCurType1
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
IF (##FETCH_STATUS>=0)
BEGIN
SET #SQL2 = #SQL2 + #crlf + ' ' + '[' + #Field + ']' + ' = Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
END
WHILE (##FETCH_STATUS<>-1)
BEGIN
IF (##FETCH_STATUS<>-2)
SET #SQL2 = #SQL2 + #crlf + ' ,' + '[' + #Field + ']' + ' = Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurType1 INTO #Field, #NullRep
END
CLOSE myCurType1
IF #UseLastUpdated>0 SET #SQL2 = #SQL2 + #crlf + ' ,LastUpdated = GetDate()'
SET #SQL3 = ' WHEN NOT MATCHED THEN'
SET #SQL3 = #SQL3 + #crlf + ' INSERT ('
OPEN myCurAll
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
IF (##FETCH_STATUS>=0)
BEGIN
SET #SQL3 = #SQL3 + #crlf + ' ' + '[' + #Field + ']'
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
END
WHILE (##FETCH_STATUS<>-1)
BEGIN
IF (##FETCH_STATUS<>-2)
SET #SQL3 = #SQL3 + #crlf + ' ,' + '[' + #Field + ']'
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
END
CLOSE myCurAll
IF #UseIsInferred>0 SET #SQL3 = #SQL3 + #crlf + ' ,IsInferred'
IF #UseFirstCreated>0 SET #SQL3 = #SQL3 + #crlf + ' ,FirstCreated'
IF #UseValidTo>0 SET #SQL3 = #SQL3 + #crlf + ' ,ValidTo'
IF #UseIsRowCurrent>0 SET #SQL3 = #SQL3 + #crlf + ' ,IsRowCurrent'
IF #UseLastUpdated>0 SET #SQL3 = #SQL3 + #crlf + ' ,LastUpdated'
SET #SQL3 = #SQL3 + #crlf + ' ) VALUES ('
OPEN myCurAll
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
IF (##FETCH_STATUS>=0)
BEGIN
SET #SQL3 = #SQL3 + #crlf + ' Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
END
WHILE (##FETCH_STATUS<>-1)
BEGIN
IF (##FETCH_STATUS<>-2)
SET #SQL3 = #SQL3 + #crlf + ' ,Source.' + '[' + #Field + ']'
FETCH NEXT FROM myCurAll INTO #Field, #NullRep
END
CLOSE myCurAll
IF #UseIsInferred>0 SET #SQL3 = #SQL3 + #crlf + ' ,0'
IF #UseFirstCreated>0 SET #SQL3 = #SQL3 + #crlf + ' ,GetDate()'
IF #UseValidTo>0 SET #SQL3 = #SQL3 + #crlf + ' ,NULL'
IF #UseIsRowCurrent>0 SET #SQL3 = #SQL3 + #crlf + ' ,1'
IF #UseLastUpdated>0 SET #SQL3 = #SQL3 + #crlf + ' ,GetDate()'
SET #SQL3 = #SQL3 + #crlf + ' );'
--clean up
DEALLOCATE myCurType1
DEALLOCATE myCurAll
DEALLOCATE myCurBK
IF #Execute = 1
BEGIN
EXEC(#SQL + #SQL2 + #SQL3)
END
ELSE
BEGIN
PRINT #SQL
PRINT #SQL2
PRINT #SQL3
END
END
In the stored procedure above, when I pass in the variables, it produces this code:
MERGE [DIM].[COMPANY] AS Target
USING [DBO].[DWUSD_LIVE] AS Source
ON Target.[comp] = Source.[comp]
WHEN MATCHED
AND (ISNULL(Target.[comp name],'') <> ISNULL(Source.[comp name],'')
OR ISNULL(Target.[comp description],'') <> ISNULL(Source.[comp description],'')
)
THEN UPDATE SET
[comp name] = Source.[comp name]
,[comp description] = Source.[comp description]
,LastUpdated = GetDate()
WHEN NOT MATCHED THEN
INSERT (
[comp]
,[comp name]
,[comp description]
,FirstCreated
,LastUpdated
) VALUES (
Source.[comp]
,Source.[comp name]
,Source.[comp description]
,GetDate()
,GetDate()
);
What I need to be able to do is add a DISTINCT SELECT subquery at the beginning...
MERGE [dim].[Company] AS Target
USING (
SELECT DISTINCT
[COMP NAME],
[COMP DESCRIPTION],
[COMP]
FROM [dbo].[DWUSD_LIVE]
) AS Source
So that when it looks at the source (staging table) it does a SELECT DISTINCT on the same columns found in the dimension but not including the audit columns (FirstCreated / LastUpdated).
My staging table has duplicate records, thus I only need to SELECT DISTINCT otherwise I end up with multiple records in my dimension.

It looks like you pass the table you want to use as a source to the stored procedure in these variables:
#ETLTable varchar(50),
#ETLSchema varchar(50),
Those same variables are used in defining the source:
--Now start building up the dynamic SQL
SET #SQL ='MERGE [' + #Schema + '].[' + #Dimension + '] AS Target'
SET #SQL = #SQL + #crlf + 'USING [' + #ETLSchema + '].[' + #ETLTable + '] AS Source'
I believe, as long as you have the same columns you would need from the actual source table, you can take the distinct query you want to use, create a view with it and pass that table to the stored proc.
CREATE VIEW dbo.vwDWUSD_LIVE
AS
SELECT DISTINCT
[COMP NAME],
[COMP DESCRIPTION],
[COMP]
FROM [dbo].[DWUSD_LIVE]
GO
The exec statement would look something like:
EXEC [dbo].[GenerateMerge] 'COMPANY', 'DIM', 'vwDWUSD_LIVE', 'DBO', 1
Also, you won't have to modify the stored proc, which looks like it may be called by other processes and if you have this same situation with other tables, you can apply a similar solution.

Related

The operation failed because an index or statistics with name {Index name }already exists on table

When Running the below script to create indexes on Table from another it fails trying to re-create the same index. Error "The operation failed because an index or statistics with already exists on table". Here is the code. Pls let me know if you have any questions
DECLARE
#schema sysname
,#TableName varchar(255)
,#IncludeIndexes BIT
,#NewTableName varchar(255)
SET #TableName = 'SourceTableNameHere'
SET #NewTableName ='TargetTableNameHere'
SET #IncludeIndexes = 1
set #schema = 'dbo'
IF #IncludeIndexes = 1
BEGIN
DECLARE #IndexId int, #IndexName nvarchar(255), #IsUnique bit, #IsUniqueConstraint bit, #FilterDefinition nvarchar(max),#IndexType int,#IndexColumnID int
DECLARE indexcursor CURSOR FOR
select distinct sc.index_id,i.name, is_unique, is_unique_constraint, filter_definition,i.type,index_column_id
FROM sys.index_columns sc
JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id
LEFT JOIN sys.indexes i on sc.object_id = i.object_id AND sc.index_id = i.index_id
WHERE OBJECT_NAME(sc.object_id) = #TableName AND sc.object_id = i.object_id AND sc.index_id = i.index_id
ORDER BY index_column_id ASC
OPEN indexcursor;
WHILE 1 = 1
BEGIN
FETCH NEXT FROM indexcursor INTO #IndexId, #IndexName, #IsUnique, #IsUniqueConstraint, #FilterDefinition, #IndexType,#IndexColumnID ;
IF ##fetch_status <> 0
BREAK
-- WHILE ##FETCH_STATUS = 0
--BEGIN
DECLARE #Unique nvarchar(255)
SET #Unique = CASE WHEN #IsUnique = 1 THEN ' UNIQUE ' ELSE '' END
DECLARE #KeyColumns nvarchar(max), #IncludedColumns nvarchar(max)
SET #KeyColumns = ''
SET #IncludedColumns = ''
select #KeyColumns = #KeyColumns + '[' + c.name + '] ' + CASE WHEN is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END + ',' from sys.index_columns ic
inner join sys.columns c ON c.object_id = ic.object_id and c.column_id = ic.column_id
where index_id = #IndexId and ic.object_id = object_id('[' + #schema + '].[' + #TableName + ']') and key_ordinal > 0
order by index_column_id
select #IncludedColumns = #IncludedColumns + '[' + c.name + '],' from sys.index_columns ic
inner join sys.columns c ON c.object_id = ic.object_id and c.column_id = ic.column_id
where index_id = #IndexId and ic.object_id = object_id('[' + #schema + '].[' + #TableName + ']') and key_ordinal = 0
order by index_column_id
IF LEN(#KeyColumns) > 0
SET #KeyColumns = LEFT(#KeyColumns, LEN(#KeyColumns) - 1)
IF LEN(#IncludedColumns) > 0
BEGIN
SET #IncludedColumns = ' INCLUDE (' + LEFT(#IncludedColumns, LEN(#IncludedColumns) - 1) + ')'
END
IF #FilterDefinition IS NULL
SET #FilterDefinition = ''
ELSE
SET #FilterDefinition = 'WHERE ' + #FilterDefinition + ' '
SET #IndexName = Replace(#IndexName,#TableName,#NewTableName)
/* IF #IndexType = 1 -- Clustered
BEGIN exec('CREATE ' + #Unique + ' CLUSTERED INDEX [' + #IndexName + '] ON [' + #schema + '].[' + #NewTableName + '] (' + #KeyColumns + ')' + #IncludedColumns + #FilterDefinition)
END */
IF #IndexType = 2 --Nonclustered
BEGIN exec('CREATE ' + #Unique + ' NONCLUSTERED INDEX [' + #IndexName + '] ON [' + #schema + '].[' + #NewTableName + '] (' + #KeyColumns + ')' + #IncludedColumns + #FilterDefinition)
END
/* IF #IsUniqueConstraint =1
BEGIN
SET #IndexName = REPLACE(#IndexName, #TableName, #NewTableName)
exec('ALTER TABLE [' + #schema + '].[' + #NewTableName + '] ADD CONSTRAINT [' + #IndexName + '] UNIQUE NONCLUSTERED (' + #KeyColumns + ')');
END
*/
FETCH NEXT FROM indexcursor INTO #IndexId, #IndexName, #IsUnique, #IsUniqueConstraint, #FilterDefinition,#IndexType,#IndexColumnID;
END;
CLOSE indexcursor;
DEALLOCATE indexcursor;
END
Not sure what to try next.to solve the issue

SQL Server - Get a list of datatypes, max length, if its an identity and if its a primary key without object_ID function

I need a query that gets the datatype, max length, if its an identity and if its a primary key from a specific table_name without the use of the object_id function. So far what I have right now (and also found this somewhere on stackoverflow):
SELECT col.COLUMN_NAME AS ColumnName
, col.DATA_TYPE AS DataType
, col.CHARACTER_MAXIMUM_LENGTH AS MaxLength
, COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsIdentity')AS IS_IDENTITY
, CAST(ISNULL(pk.is_primary_key, 0)AS bit)AS IsPrimaryKey
FROM INFORMATION_SCHEMA.COLUMNS AS col
LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
, o.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, i.is_primary_key
FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.objects AS o ON i.object_id = o.object_id
LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND col.COLUMN_NAME = pk.COLUMN_NAME
WHERE col.TABLE_NAME = 'tbl_users'
ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;
Im using this code for a cursor and when I try to get the value of IS_IDENTITY, its always empty or something. I feel like dynamic sql and cursor don't like the OBJECT_ID function. When I run this query without the cursor and stuff, it works perfectly fine.
FULL CODE:
ALTER Procedure [dbo].[sp_generateUpserts]
#databaseName nvarchar(MAX)
AS
BEGIN
SET NOCOUNT ON
DECLARE #tranState BIT
IF ##TRANCOUNT = 0
BEGIN
SET #tranState = 1
BEGIN TRANSACTION tranState
END
BEGIN TRY
Declare #TABLE_NAME varchar(100)
Declare #COLUMN_NAME varchar(100)
Declare #COLUMN_NAME_WITH_SPACE varchar(100)
Declare #DATA_TYPE varchar(100)
Declare #CHARACTER_MAXIMUM_LENGTH INT
Declare #IS_PK INT
Declare #IS_IDENTITY INT
DECLARE #statement nvarchar(MAX)
SET #statement = N'USE [' + #databaseName + '];
DECLARE cursorUpsert CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
ORDER BY TABLE_NAME'
EXECUTE sp_executesql #statement
DECLARE #use_db nvarchar(max)
DECLARE #generateSpStatement varchar(MAX)
DECLARE #spParameters varchar(MAX) = ''
DECLARE #whereColumns varchar(MAX) = ''
DECLARE #updateStatement varchar(MAX) = ''
DECLARE #insertStatement varchar(MAX) = ''
DECLARE #valueStatement varchar(MAX) = ''
OPEN cursorUpsert
FETCH NEXT FROM cursorUpsert
INTO #TABLE_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #statementColumns nvarchar(MAX)
SET #statementColumns = N'USE [' + #databaseName + '];
DECLARE cursorUpsertColumns CURSOR FOR
SELECT col.COLUMN_NAME
, col.DATA_TYPE
, col.CHARACTER_MAXIMUM_LENGTH
, COLUMNPROPERTY(OBJECT_ID(QUOTENAME(col.TABLE_SCHEMA) + ''.'' + QUOTENAME(col.TABLE_NAME)), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
, CAST(ISNULL(pk.is_primary_key, 0) AS bit) AS IS_PK
FROM INFORMATION_SCHEMA.COLUMNS AS col
LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
, o.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, i.is_primary_key
FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.objects AS o ON i.object_id = o.object_id
LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND col.COLUMN_NAME = pk.COLUMN_NAME
WHERE col.TABLE_NAME = ''' + #TABLE_NAME + '''
ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;'
EXECUTE sp_executesql #statementColumns
OPEN cursorUpsertColumns
FETCH NEXT FROM cursorUpsertColumns
INTO #COLUMN_NAME, #DATA_TYPE, #CHARACTER_MAXIMUM_LENGTH, #IS_IDENTITY, #IS_PK
WHILE ##FETCH_STATUS = 0
BEGIN
-- Parameters for the SP
IF #COLUMN_NAME LIKE '% %'
BEGIN
SET #COLUMN_NAME_WITH_SPACE = #COLUMN_NAME
SET #COLUMN_NAME_WITH_SPACE = REPLACE(#COLUMN_NAME_WITH_SPACE,' ','_')
SET #spParameters = #spParameters + CHAR(13) + '#' + #COLUMN_NAME_WITH_SPACE + ' ' + #DATA_TYPE
END
ELSE
BEGIN
SET #spParameters = #spParameters + CHAR(13) + '#' + #COLUMN_NAME + ' ' + #DATA_TYPE
END
IF #DATA_TYPE IN ('varchar', 'nvarchar', 'char', 'nchar')
BEGIN
IF #CHARACTER_MAXIMUM_LENGTH = '-1'
BEGIN
SET #spParameters = #spParameters + '(MAX)'
END
ELSE
BEGIN
SET #spParameters = #spParameters + '(' + CAST(#CHARACTER_MAXIMUM_LENGTH As Varchar(10)) + ')'
END
END
-- Add a comma after each parameter
SET #spParameters = #spParameters + ', '
IF #COLUMN_NAME IN ('top')
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + '[' + #COLUMN_NAME + '],'
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME + ','
END
ELSE IF #COLUMN_NAME LIKE '% %'
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME_WITH_SPACE + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME_WITH_SPACE + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + '['+ #COLUMN_NAME + '],'
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME_WITH_SPACE + ','
END
ELSE
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + #COLUMN_NAME + '=#' + #COLUMN_NAME + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + #COLUMN_NAME + '=#' + #COLUMN_NAME + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + #COLUMN_NAME + ','
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME + ','
END
FETCH NEXT FROM cursorUpsertColumns
INTO #COLUMN_NAME, #DATA_TYPE, #CHARACTER_MAXIMUM_LENGTH, #IS_IDENTITY, #IS_PK
if ##FETCH_STATUS!=0
begin
-- Last row, remove things
-- Remove the last AND word
SET #whereColumns = left (#whereColumns, len(#whereColumns) -3)
-- Remove the last comma from the parameter
SET #spParameters = left (#spParameters, len(#spParameters) -1)
-- Remove the last comma from the updateStatement
SET #updateStatement = left (#updateStatement, len(#updateStatement) -1)
-- Remove the last comma from the insertStatement
SET #insertStatement = left (#insertStatement, len(#insertStatement) -1)
-- Remove the last comma from the valueStatement
SET #valueStatement = left (#valueStatement, len(#valueStatement) -1)
end
END;
CLOSE cursorUpsertColumns;
DEALLOCATE cursorUpsertColumns;
--- End Cursor Columns
-- Generate the SP
SET #generateSpStatement = 'CREATE Procedure [dbo].[sp_' + #TABLE_NAME + '_upsert]' + #spParameters
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'AS BEGIN' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SET NOCOUNT ON' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #tranState BIT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF ##TRANCOUNT = 0' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'BEGIN' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'SET #tranState = 1' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'set transaction isolation level serializable' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'BEGIN TRANSACTION tranState' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'END' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'BEGIN TRY' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF EXISTS(SELECT 1 FROM ' + #TABLE_NAME + ' WITH (updlock) WHERE' + #whereColumns + ')' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'UPDATE ' + #TABLE_NAME + ' SET' + #updateStatement + ' WHERE ' + #whereColumns + ';' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'ELSE' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'INSERT INTO ' + #TABLE_NAME + ' ('+ #insertStatement + ') VALUES (' + #valueStatement + ');' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF #tranState = 1 AND XACT_STATE() = 1' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'COMMIT TRANSACTION tranState' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END TRY' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'BEGIN CATCH' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_Message VARCHAR(5000)' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_Severity INT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_State INT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_Message = ERROR_MESSAGE()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_Severity = ERROR_SEVERITY()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_State = ERROR_STATE()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF #tranState = 1 AND XACT_STATE() <> 0' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'ROLLBACK TRANSACTION' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'RAISERROR (#Error_Message, #Error_Severity, #Error_State)' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END CATCH' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END' + CHAR(13)
--print(#generateSpStatement)
-- Reset Variables
SET #generateSpStatement = ''
SET #spParameters = ''
SET #whereColumns = ''
SET #updateStatement = ''
SET #insertStatement = ''
SET #valueStatement = ''
FETCH NEXT FROM cursorUpsert
INTO #TABLE_NAME
END;
CLOSE cursorUpsert;
DEALLOCATE cursorUpsert;
IF #tranState = 1
AND XACT_STATE() = 1
COMMIT TRANSACTION tranState
END TRY
BEGIN CATCH
DECLARE #Error_Message VARCHAR(5000)
DECLARE #Error_Severity INT
DECLARE #Error_State INT
SELECT #Error_Message = ERROR_MESSAGE()
SELECT #Error_Severity = ERROR_SEVERITY()
SELECT #Error_State = ERROR_STATE()
IF #tranState = 1 AND XACT_STATE() <> 0
ROLLBACK TRANSACTION
RAISERROR (#Error_Message, #Error_Severity, #Error_State)
END CATCH
END
I feel like dynamic sql and cursor don't like the OBJECT_ID function.
It has nothing to do with OBJECT_ID but most likely incorrect double qouting when using with dynamic string:
COLUMNPROPERTY(OBJECT_ID(''['' + col.TABLE_SCHEMA + ''].['' + col.TABLE_NAME + '']''), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
Anyway you should avoid manually adding [ and use QUOTENAME instead:
COLUMNPROPERTY(OBJECT_ID(QUOTENAME(col.TABLE_SCHEMA) + ''.'' + QUOTENAME(col.TABLE_NAME)), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
It's a common case and it would be really nice if here-strings/text quoting were supported.
Another slightly simpler way of getting this information would be something like..
Declare #Schema SYSNAME = 'dbo'
, #Table SYSNAME= 'Orders'
SELECT
name Column_Name
, system_type_name Data_Type
, max_length Max_Length
, is_identity_column Is_Identity_Column
, ISNULL(c.PK_Column,0) Is_Primary_Key_Column
FROM sys.dm_exec_describe_first_result_set (N'SELECT * FROM '+ #Schema +'.' + #Table, null, 0) r
OUTER APPLY (
SELECT 1 PK_Column
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE s
WHERE OBJECTPROPERTY(OBJECT_ID(s.CONSTRAINT_SCHEMA + '.' + QUOTENAME(s.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND s.TABLE_NAME = #Table
AND s.TABLE_SCHEMA = #Schema
AND r.name COLLATE DATABASE_DEFAULT = s.COLUMN_NAME
) c(PK_Column)
You can put this code inside a function and simply call this function cross applying it with sys.tables catalog view.
The dynamic management view sys.dm_exec_describe_first_result_set has lots of other useful information too.
Lets suppose you create a function like this..
CREATE FUNCTION dbo.fn_get_Column_Info (
#Schema SYSNAME
, #Table SYSNAME)
RETURNS TABLE
AS
RETURN
(
SELECT
name Column_Name
, system_type_name Data_Type
, max_length Max_Length
, is_identity_column Is_Identity_Column
, ISNULL(c.PK_Column,0) Is_Primary_Key_Column
FROM sys.dm_exec_describe_first_result_set (N'SELECT * FROM '+ #Schema +'.' + #Table, null, 0) r
OUTER APPLY (
SELECT 1 PK_Column
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE s
WHERE OBJECTPROPERTY(OBJECT_ID(s.CONSTRAINT_SCHEMA + '.' + QUOTENAME(s.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND s.TABLE_NAME = #Table
AND s.TABLE_SCHEMA = #Schema
AND r.name COLLATE DATABASE_DEFAULT = s.COLUMN_NAME
) c(PK_Column)
);
GO
Then your query to get all the information you need would be as simple as..
SELECT s.name , t.name, f.*
FROM sys.schemas s
INNER JOIN sys.Tables t ON s.schema_id = t.schema_id
CROSS APPLY dbo.fn_get_Column_Info(s.name , t.name) f;
No need for any cursor or dynamic SQL, unless you want to do this for all the databases on a server. But even if you had to do that for all databases it would be a much simpler cursor.

SQL Server : Search for a string across all the databases and list all the databases, tables and corresponding columns

I am wondering if there is a way I can view all the databases and the corresponding tables where a specific string is present in SQL Server 2012.
I was able to search for a string in all the tables in a particular database by using a stored procedure below which I found online. But I would like to search it across all the databases.
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + 'WITH (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
And when I execute the below query, it lists all the tables along with the column names.
exec SearchAllTables "B2"
OUTPUT:
ColumnName ColumnValue
[dbo].[msm_temp].[molecule_nm] B2
[dbo].[msm_temp1].[molecule_nm] B2
[dbo].[msm_temp2].[molecule_nm] B2
[dbo].[msm_temp3].[molecule_nm] B2
[dbo].[msm_temp4].[molecule_nm] B2
How do I solve the problem?
You can use this stored procedure with value for search like this :
exec SearchAllDatabases #SearchTerm = '%B2%'
This can help you to search everywhere but if you have too much data in your databases this will take time to execute.
Stored procedure :
CREATE PROCEDURE dbo.SearchAllDatabases
#SearchTerm NVARCHAR(255) = NULL
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF #SearchTerm IS NULL OR #SearchTerm NOT LIKE N'%[^%^_]%'
BEGIN
RAISERROR(N'Please enter a valid search term.', 11, 1);
RETURN;
END
CREATE TABLE #results
(
[database] SYSNAME,
[schema] SYSNAME,
[table] SYSNAME,
[column] SYSNAME,
ExampleValue NVARCHAR(1000)
);
DECLARE
#DatabaseCommands NVARCHAR(MAX) = N'',
#ColumnCommands NVARCHAR(MAX) = N'';
SELECT #DatabaseCommands = #DatabaseCommands + N'
EXEC ' + QUOTENAME(name) + '.sys.sp_executesql
#ColumnCommands, N''#SearchTerm NVARCHAR(MAX)'', #SearchTerm;'
FROM sys.databases
WHERE database_id > 4 -- non-system databases
AND[state] = 0-- online
AND user_access = 0; -- multi-user
SET #ColumnCommands = N'DECLARE #q NCHAR(1),
#SearchCommands NVARCHAR(MAX);
SELECT #q = NCHAR(39),
#SearchCommands = N''DECLARE #VSearchTerm VARCHAR(255) = #SearchTerm;'';
SELECT #SearchCommands = #SearchCommands + CHAR(10) + N''
SELECT TOP(1)
[db] = DB_NAME(),
[schema] = N'' + #q + s.name + #q + '',
[table] = N'' + #q + t.name + #q + '',
[column] = N'' + #q + c.name + #q + '',
ExampleValue = LEFT('' + QUOTENAME(c.name) + '', 1000)
FROM '' + QUOTENAME(s.name) + ''.'' + QUOTENAME(t.name) + ''
WHERE '' + QUOTENAME(c.name) + N'' LIKE #'' + CASE
WHEN c.system_type_id IN(35, 167, 175) THEN ''V''
ELSE '''' END + ''SearchTerm;''
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.columns AS c
ON t.[object_id] = c.[object_id]
WHERE c.system_type_id IN (35, 99, 167, 175, 231, 239)
AND c.max_length >= LEN(#SearchTerm);
PRINT #SearchCommands;
EXEC sys.sp_executesql #SearchCommands,
N''#SearchTerm NVARCHAR(255)'', #SearchTerm;';
INSERT #Results
(
[database],
[schema],
[table],
[column],
ExampleValue
)
EXEC[master].sys.sp_executesql #DatabaseCommands,
N'#ColumnCommands NVARCHAR(MAX), #SearchTerm NVARCHAR(255)',
#ColumnCommands, #SearchTerm;
SELECT[Searched for] = #SearchTerm;
SELECT[database],[schema],[table],[column],ExampleValue
FROM #Results
ORDER BY[database],[schema],[table],[column];
END
GO
I hope this helps you.

Dynamically Generate TVP from an existing table?

Is there is a way to generate a TVP from an existing table? I have tried this, https://dba.stackexchange.com/questions/12596/using-tables-as-table-valued-parameters-tvp but it's showing me syntax error?
-- you would pass these two in as parameters of course:
DECLARE
#TableName SYSNAME = N'LocationTable',
#TypeName SYSNAME = N'LocationTypeTable';
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql = #sql + N',' + CHAR(13) + CHAR(10) + CHAR(9)
+ QUOTENAME(c.name) + ' '
+ s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN
'(' + CONVERT(VARCHAR(12), (c.max_length/
(CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END)) + ')'
ELSE '' END
-- need much more conditionals here for other data types
FROM sys.columns AS c
INNER JOIN sys.types AS s
ON c.system_type_id = s.system_type_id
AND c.user_type_id = s.user_type_id
WHERE c.[object_id] = OBJECT_ID(#TableName);
SELECT #sql = N'CREATE TYPE ' + #TypeName
+ ' AS TABLE ' + CHAR(13) + CHAR(10) + (' + STUFF(#sql, 1, 1, '')
+ CHAR(13) + CHAR(10) + ');';
PRINT #sql;
-- EXEC sp_executesql #sql;
I have made modifications to your code above. This code executes but returns no values. What are you looking for exactly.
-- you would pass these two in as parameters of course:
DECLARE
#TableName SYSNAME
Set #TableName = N'LocationTable'
DECLARE
#TypeName SYSNAME
Set #TypeName = N'LocationTypeTable'
DECLARE #sql NVARCHAR(4000)
SET #sql= N'';
SELECT #sql = N',' + CHAR(13) + CHAR(10) + CHAR(9)
+ QUOTENAME(c.name) + ' '
+ s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN
-- '(' +
CONVERT(VARCHAR(12), (c.max_length/
(CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END)))
-- + ')'
ELSE '' END
-- need much more conditionals here for other data types
FROM sys.columns AS c
INNER JOIN sys.types AS s
ON c.system_type_id = s.system_type_id
AND c.user_type_id = s.user_type_id
WHERE c.[object_id] = OBJECT_ID(#TableName);
SELECT #sql = N'CREATE TYPE ' + #TypeName
+ ' AS TABLE ' + CHAR(13) + CHAR(10) + '(' + STUFF(#sql, 1, 1, '')
+ CHAR(13) + CHAR(10) + ');';
PRINT #sql;
-- EXEC sp_executesql #sql;

Generate SQL Create Scripts for existing tables with Query

I'm trying to get the CREATE scripts for existing tables within SQL Server 2008. I assume I can do this by querying the sys.tables somehow, however this isn't returning me the CREATE script data.
Possible this be helpful for you. This script generate indexes, FK's, PK and common structure for any table.
For example -
DDL:
CREATE TABLE [dbo].[WorkOut](
[WorkOutID] [bigint] IDENTITY(1,1) NOT NULL,
[TimeSheetDate] [datetime] NOT NULL,
[DateOut] [datetime] NOT NULL,
[EmployeeID] [int] NOT NULL,
[IsMainWorkPlace] [bit] NOT NULL,
[DepartmentUID] [uniqueidentifier] NOT NULL,
[WorkPlaceUID] [uniqueidentifier] NULL,
[TeamUID] [uniqueidentifier] NULL,
[WorkShiftCD] [nvarchar](10) NULL,
[WorkHours] [real] NULL,
[AbsenceCode] [varchar](25) NULL,
[PaymentType] [char](2) NULL,
[CategoryID] [int] NULL,
[Year] AS (datepart(year,[TimeSheetDate])),
CONSTRAINT [PK_WorkOut] PRIMARY KEY CLUSTERED
(
[WorkOutID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[WorkOut] ADD
CONSTRAINT [DF__WorkOut__IsMainW__2C1E8537] DEFAULT ((1)) FOR [IsMainWorkPlace]
ALTER TABLE [dbo].[WorkOut] WITH CHECK ADD CONSTRAINT [FK_WorkOut_Employee_EmployeeID] FOREIGN KEY([EmployeeID])
REFERENCES [dbo].[Employee] ([EmployeeID])
ALTER TABLE [dbo].[WorkOut] CHECK CONSTRAINT [FK_WorkOut_Employee_EmployeeID]
Query:
DECLARE #table_name SYSNAME
SELECT #table_name = 'dbo.WorkOut'
DECLARE
#object_name SYSNAME
, #object_id INT
SELECT
#object_name = '[' + s.name + '].[' + o.name + ']'
, #object_id = o.[object_id]
FROM sys.objects o WITH (NOWAIT)
JOIN sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE s.name + '.' + o.name = #table_name
AND o.[type] = 'U'
AND o.is_ms_shipped = 0
DECLARE #SQL NVARCHAR(MAX) = ''
;WITH 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] = #object_id
),
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
WHERE k.parent_object_id = #object_id
)
SELECT #SQL = 'CREATE TABLE ' + #object_name + CHAR(13) + '(' + CHAR(13) + STUFF((
SELECT CHAR(9) + ', [' + c.name + '] ' +
CASE WHEN c.is_computed = 1
THEN 'AS ' + cc.[definition]
ELSE UPPER(tp.name) +
CASE WHEN tp.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')'
WHEN tp.name IN ('nvarchar', 'nchar', 'ntext')
THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(5)) END + ')'
WHEN tp.name IN ('datetime2', 'time2', 'datetimeoffset')
THEN '(' + CAST(c.scale AS VARCHAR(5)) + ')'
WHEN tp.name = 'decimal'
THEN '(' + CAST(c.[precision] AS VARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(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 dc.[definition] IS NOT NULL THEN ' DEFAULT' + dc.[definition] ELSE '' END +
CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(ic.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END
END + CHAR(13)
FROM sys.columns c WITH (NOWAIT)
JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
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] = #object_id
ORDER BY c.column_id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
+ ISNULL((SELECT CHAR(9) + ', CONSTRAINT [' + k.name + '] PRIMARY KEY (' +
(SELECT STUFF((
SELECT ', [' + c.name + '] ' + CASE WHEN ic.is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END
FROM sys.index_columns ic WITH (NOWAIT)
JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
WHERE ic.is_included_column = 0
AND ic.[object_id] = k.parent_object_id
AND ic.index_id = k.unique_index_id
FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ''))
+ ')' + CHAR(13)
FROM sys.key_constraints k WITH (NOWAIT)
WHERE k.parent_object_id = #object_id
AND k.[type] = 'PK'), '') + ')' + CHAR(13)
+ ISNULL((SELECT (
SELECT CHAR(13) +
'ALTER TABLE ' + #object_name + ' WITH'
+ CASE WHEN fk.is_not_trusted = 1
THEN ' NOCHECK'
ELSE ' CHECK'
END +
' ADD CONSTRAINT [' + fk.name + '] FOREIGN KEY('
+ STUFF((
SELECT ', [' + k.cname + ']'
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(''), TYPE).value('.', '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(''), TYPE).value('.', '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 ' + #object_name + ' CHECK CONSTRAINT [' + 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 = #object_id
FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)')), '')
+ ISNULL(((SELECT
CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END
+ ' NONCLUSTERED INDEX [' + i.name + '] ON ' + #object_name + ' (' +
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(''), TYPE).value('.', '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(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '') + CHAR(13)
FROM sys.indexes i WITH (NOWAIT)
WHERE i.[object_id] = #object_id
AND i.is_primary_key = 0
AND i.[type] = 2
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
), '')
PRINT #SQL
--EXEC sys.sp_executesql #SQL
Output:
CREATE TABLE [dbo].[WorkOut]
(
[WorkOutID] BIGINT NOT NULL IDENTITY(1,1)
, [TimeSheetDate] DATETIME NOT NULL
, [DateOut] DATETIME NOT NULL
, [EmployeeID] INT NOT NULL
, [IsMainWorkPlace] BIT NOT NULL DEFAULT((1))
, [DepartmentUID] UNIQUEIDENTIFIER NOT NULL
, [WorkPlaceUID] UNIQUEIDENTIFIER NULL
, [TeamUID] UNIQUEIDENTIFIER NULL
, [WorkShiftCD] NVARCHAR(10) COLLATE Cyrillic_General_CI_AS NULL
, [WorkHours] REAL NULL
, [AbsenceCode] VARCHAR(25) COLLATE Cyrillic_General_CI_AS NULL
, [PaymentType] CHAR(2) COLLATE Cyrillic_General_CI_AS NULL
, [CategoryID] INT NULL
, [Year] AS (datepart(year,[TimeSheetDate]))
, CONSTRAINT [PK_WorkOut] PRIMARY KEY ([WorkOutID] ASC)
)
ALTER TABLE [dbo].[WorkOut] WITH CHECK ADD CONSTRAINT [FK_WorkOut_Employee_EmployeeID] FOREIGN KEY([EmployeeID]) REFERENCES [dbo].[Employee] ([EmployeeID])
ALTER TABLE [dbo].[WorkOut] CHECK CONSTRAINT [FK_WorkOut_Employee_EmployeeID]
CREATE NONCLUSTERED INDEX [IX_WorkOut_WorkShiftCD_AbsenceCode] ON [dbo].[WorkOut] ([WorkShiftCD] ASC, [AbsenceCode] ASC)
INCLUDE ([WorkOutID], [WorkHours])
Also check this article -
How to Generate a CREATE TABLE Script For an Existing Table: Part 1
do you mean you wish to create a TSQL script which generates a CREATE script, or use the Management tools in SQL SERVER Management Studio to generate a Create script?
If it's the latter, it's a simply matter of right-clicking a table, and selecting Script Table As -> Create To -> New Query Window.
If you want the whole database scripted, then right click the database and select Tasks--> Generate Scripts... and then follow the wizard
otherwise it's a matter of selecting all sorts of fun things out of the various system tables.
I realize this question is old, but it recently popped up in a search I just ran, so I thought I'd post an alternative to the above answer.
If you are looking to generate create scripts programmatically in .Net, I would highly recommend looking into Server Management Objects (SMO) or Distributed Management Objects (DMO) -- depending on which version of SQL Server you are using (the former is 2005+, the latter 2000). Using these libraries, scripting a table is as easy as:
Server server = new Server(".");
Database northwind = server.Databases["Northwind"];
Table categories = northwind.Tables["Categories"];
StringCollection script = categories.Script();
string[] scriptArray = new string[script.Count];
script.CopyTo(scriptArray, 0);
Here is a blog post with more information.
First of all I love the script written by devart and I wanted to use it, but I found some limitation, so I decided to improve it:
I fixed the bug that limits the script at 4000 chars (it's still possible that some crazy table still exceeds the limits)
I fixed the bug/limitation in case the table uses a nonclustered primary key
I replaced '[' with quotename
I added the name of the default constraints
I changed the logic to identify the source table
I added the possibility to drop and recreate the table and its FKs
I added the possibility to generate specific attributes
I added the support for table compression
I added the possibility the generate the scripts for any number of tables
I fixed the limitation of 4000 varchar() when printing the result
I replaced '' with N''
I added the option to generate messages during the execution, because my final script (with the insert into) can take so long that I want to know what it's doing
I added the generation of an "Insert into"
I didn't have time to test it properly and I tested it only on SQL Server 2012/4
The next version will change the generation of FKs because they need to be added at the end. Otherwise they may fail.
Any comment will be appreciated.
set transaction isolation level read uncommitted;
SET NOCOUNT ON;
SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;
-- http://stackoverflow.com/questions/12639948/sql-nvarchar-and-varchar-limits
--NB: Crazy table can still have truncation at 4000 because of unexpected number of indexes or other very long list of columns/defaults etc
-- triggers are not supported
-- xml indexes are not supported
DECLARE #Tables table(id int identity(1,1), [name] sysname);
insert into #Tables([name])
values
('<yourSchema>.<youTableName>')
,('<yourSchema2>.<youTableName2>')
;
DECLARE #object_id int;
DECLARE #SourceDatabase nvarchar(max) = N'SourceTest'; --this is used only by the insert
DECLARE #TargetDatabase nvarchar(max) = N'DescTest'; --this is used only by the insert and USE <DBName>
--- options ---
DECLARE #UseTransaction bit = 0;
DECLARE #GenerateUseDatabase bit = 0;
DECLARE #GenerateFKs bit = 1;
DECLARE #GenerateIdentity bit = 1;
DECLARE #GenerateCollation bit = 0;
DECLARE #GenerateCreateTable bit = 1;
DECLARE #GenerateIndexes bit = 1;
DECLARE #GenerateConstraints bit = 1;
DECLARE #GenerateKeyConstraints bit = 1;
DECLARE #GenerateConstraintNameOfDefaults bit = 1;
DECLARE #GenerateDropIfItExists bit = 1;
DECLARE #GenerateDropFKIfItExists bit = 0;
DECLARE #GenerateDelete bit = 0;
DECLARE #GenerateInsertInto bit = 0;
DECLARE #GenerateIdentityInsert int = 0; --0 ignore set,but add column; 1 generate; 2 ignore set and column
DECLARE #GenerateSetNoCount int = 2; --0 ignore set,1=set on, 2=set off
DECLARE #GenerateMessages bit = 1; --print with no wait
DECLARE #GenerateDataCompressionOptions bit = 1; --TODO: generates the compression option only of the table, not the indexes
--NB: the compression options reflects the design value.
--The actual compression of a the page is saved here
--SELECT * from sys.dm_db_database_page_allocations(DB_ID(), #object_ID, 0, 1, 'DETAILED')
-----------------------------------------------------------------------------
------------------------------------------------------------------------------
--- Let's play
DECLARE #DataTypeSpacer int = 45; --this is just to improve the formatting of the script ...
DECLARE #name sysname;
DECLARE #SQL NVARCHAR(MAX) = N''
DECLARE db_cursor CURSOR FOR SELECT [name] from #Tables
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #object_id = object_ID(#name)
goto CreateScript;
backFromCreateScript:
FETCH NEXT FROM db_cursor INTO #name
END
CLOSE db_cursor
DEALLOCATE db_cursor
return;
CreateScript:
DECLARE #CR NVARCHAR(max) = NCHAR(13);
DECLARE #TB NVARCHAR(max) = NCHAR(9);
DECLARE #CurrentIndent nvarchar(max) = ''
;WITH 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] = #object_id
),
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
WHERE k.parent_object_id = #object_id and #GenerateFKs = 1
)
SELECT #SQL =
-------------------- USE DATABASE --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #GenerateUseDatabase = 1
THEN N'USE ' + #TargetDatabase + N';' + #CR
ELSE N'' END
as nvarchar(max))
+
-------------------- SET NOCOUNT --------------------------------------------------------------------------------------------------
CAST(
CASE #GenerateSetNoCount
WHEN 1 THEN N'SET NOCOUNT ON;' + #CR
WHEN 2 THEN N'SET NOCOUNT OFF;' + #CR
ELSE N'' END
as nvarchar(max))
+
-------------------- USE TRANSACTION --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #UseTransaction = 1
THEN
N'SET XACT_ABORT ON' + #CR
+ N'BEGIN TRY' + #CR
+ N'BEGIN TRAN' + #CR
ELSE N'' END
as nvarchar(max))
+
-------------------- DROP SYNONYM --------------------------------------------------------------------------------------------------
CASE WHEN #GenerateDropIfItExists = 1
THEN
CAST(
N'IF OBJECT_ID(''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''',''SN'') IS NOT NULL DROP SYNONYM ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N';' + #CR
as nvarchar(max))
ELSE
CAST(
N''
as nvarchar(max))
END
+
-------------------- DROP IS Exists --------------------------------------------------------------------------------------------------
CASE WHEN #GenerateDropIfItExists = 1
THEN
--Drop table if exists
CAST(
N'IF OBJECT_ID(''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''',''U'') IS NOT NULL DROP TABLE ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N';' + #CR
as nvarchar(max))
+ #CR
ELSE N'' END
+
-------------------- DROP IS Exists --------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 and #GenerateDropFKIfItExists = 1 THEN
N'RAISERROR(''DROP CONSTRAINTS OF %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
CASE WHEN #GenerateDropFKIfItExists = 1
THEN
--Drop foreign keys
ISNULL(((
SELECT
CAST(
N'ALTER TABLE ' + quotename(s.name) + N'.' + quotename(t.name) + N' DROP CONSTRAINT ' + RTRIM(f.name) + N';' + #CR
as nvarchar(max))
FROM sys.tables t
INNER JOIN sys.foreign_keys f ON f.parent_object_id = t.object_id
INNER JOIN sys.schemas s ON s.schema_id = f.schema_id
WHERE f.referenced_object_id = #object_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'))
,N'') + #CR
ELSE N'' END
+
--------------------- CREATE TABLE -----------------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 THEN
N'RAISERROR(''CREATE TABLE %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
CASE WHEN #GenerateCreateTable = 1 THEN
CAST(
N'CREATE TABLE ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + #CR + N'(' + #CR + STUFF((
SELECT
CAST(
#TB + N',' + quotename(c.name) + N' ' + ISNULL(replicate(' ',#DataTypeSpacer - len(quotename(c.name))),'') --isnull(replicate) then len(quotename(c.name)) > #DataTypeSpacer
+
CASE WHEN c.is_computed = 1
THEN N' AS ' + cc.[definition]
ELSE UPPER(tp.name) +
CASE WHEN tp.name IN (N'varchar', N'char', N'varbinary', N'binary', N'text')
THEN N'(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length AS NVARCHAR(5)) END + N')'
WHEN tp.name IN (N'nvarchar', N'nchar', N'ntext')
THEN N'(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length / 2 AS NVARCHAR(5)) END + N')'
WHEN tp.name IN (N'datetime2', N'time2', N'datetimeoffset')
THEN N'(' + CAST(c.scale AS NVARCHAR(5)) + N')'
WHEN tp.name = N'decimal'
THEN N'(' + CAST(c.[precision] AS NVARCHAR(5)) + N',' + CAST(c.scale AS NVARCHAR(5)) + N')'
ELSE N''
END +
CASE WHEN c.collation_name IS NOT NULL and #GenerateCollation = 1 THEN N' COLLATE ' + c.collation_name ELSE N'' END +
CASE WHEN c.is_nullable = 1 THEN N' NULL' ELSE N' NOT NULL' END +
CASE WHEN dc.[definition] IS NOT NULL THEN CASE WHEN #GenerateConstraintNameOfDefaults = 1 THEN N' CONSTRAINT ' + quotename(dc.name) ELSE N'' END + N' DEFAULT' + dc.[definition] ELSE N'' END +
CASE WHEN ic.is_identity = 1 and #GenerateIdentity = 1 THEN N' IDENTITY(' + CAST(ISNULL(ic.seed_value, N'0') AS NCHAR(1)) + N',' + CAST(ISNULL(ic.increment_value, N'1') AS NCHAR(1)) + N')' ELSE N'' END
END + #CR
AS nvarchar(Max))
FROM sys.columns c WITH (NOWAIT)
INNER JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
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] = #object_id
ORDER BY c.column_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, #TB + N' ')
as nvarchar(max))
ELSE
CAST('' as nvarchar(max))
end
+
---------------------- Key Constraints ----------------------------------------------------------------
CAST(
case when #GenerateKeyConstraints <> 1 THEN N'' ELSE
ISNULL((SELECT #TB + N', CONSTRAINT ' + quotename(k.name) + N' PRIMARY KEY ' + ISNULL(kidx.type_desc, N'') + N'(' +
(SELECT STUFF((
SELECT N', ' + quotename(c.name) + N' ' + CASE WHEN ic.is_descending_key = 1 THEN N'DESC' ELSE N'ASC' END
FROM sys.index_columns ic WITH (NOWAIT)
JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
WHERE ic.is_included_column = 0
AND ic.[object_id] = k.parent_object_id
AND ic.index_id = k.unique_index_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N''))
+ N')' + #CR
FROM sys.key_constraints k WITH (NOWAIT) LEFT JOIN sys.indexes kidx ON
k.parent_object_id = kidx.object_id and k.unique_index_id = kidx.index_id
WHERE k.parent_object_id = #object_id
AND k.[type] = N'PK'), N'') + N')' + #CR
END
as nvarchar(max))
+
CAST(
CASE
WHEN
#GenerateDataCompressionOptions = 1
AND
(SELECT top 1 data_compression_desc from sys.partitions where object_ID = #object_id and index_id = 1) <> N'NONE'
THEN
N'WITH (DATA_COMPRESSION=' + (SELECT top 1 data_compression_desc from sys.partitions where object_ID = #object_id and index_id = 1) + N')' + #CR
ELSE
N'' + #CR
END as nvarchar(max))
+
--------------------- FOREIGN KEYS -----------------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 and #GenerateDropFKIfItExists = 1 THEN
N'RAISERROR(''CREATING FK OF %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
CAST(
ISNULL((SELECT (
SELECT #CR +
N'ALTER TABLE ' + + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + + N' WITH'
+ CASE WHEN fk.is_not_trusted = 1
THEN N' NOCHECK'
ELSE N' CHECK'
END +
N' ADD CONSTRAINT ' + quotename(fk.name) + N' FOREIGN KEY('
+ STUFF((
SELECT N', ' + quotename(k.cname) + N''
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
+ N')' +
N' REFERENCES ' + quotename(SCHEMA_NAME(ro.[schema_id])) + N'.' + quotename(ro.name) + N' ('
+ STUFF((
SELECT N', ' + quotename(k.rcname) + N''
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
+ N')'
+ CASE
WHEN fk.delete_referential_action = 1 THEN N' ON DELETE CASCADE'
WHEN fk.delete_referential_action = 2 THEN N' ON DELETE SET NULL'
WHEN fk.delete_referential_action = 3 THEN N' ON DELETE SET DEFAULT'
ELSE N''
END
+ CASE
WHEN fk.update_referential_action = 1 THEN N' ON UPDATE CASCADE'
WHEN fk.update_referential_action = 2 THEN N' ON UPDATE SET NULL'
WHEN fk.update_referential_action = 3 THEN N' ON UPDATE SET DEFAULT'
ELSE N''
END
+ #CR + N'ALTER TABLE ' + + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + + N' CHECK CONSTRAINT ' + quotename(fk.name) + N'' + #CR
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 = #object_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')), N'')
as nvarchar(max))
+
--------------------- INDEXES ----------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 and #GenerateIndexes = 1 THEN
N'RAISERROR(''CREATING INDEXES OF %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
case when #GenerateIndexes = 1 THEN
CAST(
ISNULL(((SELECT
#CR + N'CREATE' + CASE WHEN i.is_unique = 1 THEN N' UNIQUE ' ELSE N' ' END
+ i.type_desc + N' INDEX ' + quotename(i.name) + N' ON ' + + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + + N' (' +
STUFF((
SELECT N', ' + quotename(c.name) + N'' + CASE WHEN c.is_descending_key = 1 THEN N' DESC' ELSE N' ASC' END
FROM index_column c
WHERE c.is_included_column = 0
AND c.index_id = i.index_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'') + N')'
+ ISNULL(#CR + N'INCLUDE (' +
STUFF((
SELECT N', ' + quotename(c.name) + N''
FROM index_column c
WHERE c.is_included_column = 1
AND c.index_id = i.index_id
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'') + N')', N'') + #CR
FROM sys.indexes i WITH (NOWAIT)
WHERE i.[object_id] = #object_id
AND i.is_primary_key = 0
AND i.[type] in (1,2)
and #GenerateIndexes = 1
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
), N'')
as nvarchar(max))
ELSE
CAST(N'' as nvarchar(max))
END
+
------------------------ #GenerateDelete ----------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 and #GenerateDelete = 1 THEN
N'RAISERROR(''TRUNCATING %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
CASE WHEN #GenerateDelete = 1 THEN
CAST(
(CASE WHEN exists (SELECT * FROM sys.foreign_keys WHERE referenced_object_id = #object_id) THEN
N'DELETE FROM ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N';' + #CR
ELSE
N'TRUNCATE TABLE ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N';' + #CR
END)
AS NVARCHAR(max))
ELSE
CAST(N'' as nvarchar(max))
END
+
------------------------- #GenerateInsertInto ----------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 and #GenerateDropFKIfItExists = 1 THEN
N'RAISERROR(''INSERTING INTO %s'',10,1, ''' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N''') WITH NOWAIT;' + #CR
ELSE N'' END) as nvarchar(max))
+
CASE WHEN #GenerateInsertInto = 1
THEN
CAST(
CASE WHEN EXISTS (SELECT * from sys.columns c where c.[object_id] = #object_id and is_identity = 1) AND #GenerateIdentityInsert = 1 THEN
N'SET IDENTITY_INSERT ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N' ON;' + #CR
ELSE
CAST('' AS nvarchar(max))
END
+
N'INSERT INTO ' + QUOTENAME(#TargetDatabase) + N'.' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N'('
+ #CR
+
(
#TB + N' ' + SUBSTRING(
(
SELECT #TB + ','+ quotename(Name) + #CR
from sys.columns c
where
c.[object_id] = #object_id
AND system_type_ID <> 189 /*timestamp*/
AND is_computed = 0
and (is_identity = 0 or #GenerateIdentityInsert in (0,1))
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
,3,99999)
)
+ N')' + #CR + N'SELECT '
+ #CR
+
(
#TB + N' ' + SUBSTRING(
(
SELECT #TB + ','+ quotename(Name) + #CR
FROM sys.columns c
WHERE c.[object_id] = #object_id
and system_type_ID <> 189 /*timestamp*/
and is_computed = 0
and (is_identity = 0 or #GenerateIdentityInsert in (0,1))
FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
,3,99999)
)
+ N'FROM ' + #SourceDatabase + N'.' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id))
+ N';' + #CR
+ CASE WHEN EXISTS (SELECT * from sys.columns c where c.[object_id] = #object_id and is_identity = 1) AND #GenerateIdentityInsert = 1 THEN
N'SET IDENTITY_INSERT ' + quotename(OBJECT_schema_name(#object_id)) + N'.' + quotename(OBJECT_NAME(#object_id)) + N' OFF;'+ #CR
ELSE
CAST('' AS nvarchar(max))
END
as nvarchar(max))
ELSE
CAST(
N''
as nvarchar(max))
END
+
-------------------- USE TRANSACTION --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #UseTransaction = 1
THEN
#CR + N'COMMIT TRAN; '
+ #CR + N'END TRY'
+ #CR + N'BEGIN CATCH'
+ #CR + N' IF XACT_STATE() IN (-1,1)'
+ #CR + N' ROLLBACK TRAN;'
+ #CR + N''
+ #CR + N' SELECT ERROR_NUMBER() AS ErrorNumber '
+ #CR + N' ,ERROR_SEVERITY() AS ErrorSeverity '
+ #CR + N' ,ERROR_STATE() AS ErrorState '
+ #CR + N' ,ERROR_PROCEDURE() AS ErrorProcedure '
+ #CR + N' ,ERROR_LINE() AS ErrorLine '
+ #CR + N' ,ERROR_MESSAGE() AS ErrorMessage; '
+ #CR + N'END CATCH'
ELSE N'' END
as nvarchar(max))
--print is limited to 4000 chars, if necessary, I use multiple print
--to maintain the consistency of the script, I split near the closest CrLF to the max chunk size
DECLARE #i int = 1;
DECLARE #maxChunk integer = 3990;
DECLARE #len integer = #maxChunk;
WHILE #i < len(#SQL)
BEGIN
IF len(#SQL) > (#i + #len)
set #len = len(substring(#SQL, #i, #maxChunk)) - CHARINDEX(#CR, reverse(substring(#SQL, #i, #len))) + 1
PRINT substring(#SQL, #i, #len)
set #i = #i + #len
set #len = #maxChunk
END
--SELECT datalength(#SQL), #sql
--EXEC sys.sp_executesql #SQL
goto backFromCreateScript;
"Easiest way is to use the built-in feature of SQL Management Studio"
but...
I have resolved it with a function and a couple of procedures.
For example, to obtain the create table for a table named 'table_name', you have to execute just the procedure called sp_ppinScriptTabla:
Exec sp_ppinScriptTabla 'table_name'
Here is the tsql script code:
Use Master
GO
Create Function sp_ppinTipoLongitud
(
#xtype int,
#length int,
#isnullable int
)
Returns Varchar(512)
As
Begin
-- Función que a partir de un tipo de datos y una logitud, devuelve el texto del tipo.
-- Por ejemplo: para xtype=varchar y length=10 devolverá "varchar(10)"
Declare #ret varchar(512)
Set #ret = ''
Select #ret = t.name +
Case When name in ('varchar', 'nvarchar', 'char', 'nchar') Then '(' + Convert(varchar, #length) + ')' Else '' End + ' ' +
Case #isnullable When 1 Then 'NULL' Else 'NOT NULL' End
From systypes t
Where t.xtype = #xtype
Return #ret
End
GO
Create Procedure sp_ppinScriptLlavesForaneas
(
#vchTabla sysname,
#vchResultado varchar(8000) output
)
AS
Begin
DECLARE #tmpFK table(
TablaF sysname,
TablaR sysname,
ColF sysname,
ColR sysname,
FKName sysname)
-- obtengo las llaves foraneas en #vchForeign
Declare #vchForeign varchar(8000), #FKName sysname, #vchColumnasF varchar(4000), #vchColumnasR varchar(4000), #ColF sysname, #ColR sysname
Declare #vchTemp varchar(1000), #TablaR sysname
Insert into #tmpFK
Select TablaF.name AS TablaF, TablaR.name AS TablaR, ColF.name AS ColF, ColR.name AS ColR, ofk.name AS FKName
From sysforeignkeys fk, sysobjects ofk, sysobjects TablaF, sysobjects TablaR,
syscolumns ColF, syscolumns ColR
Where TablaF.name = #vchTabla
And ofk.id = fk.constid
And TablaF.id = fk.fkeyid
And TablaR.id = fk.rkeyid
And ColF.id = TablaF.id And ColF.colid = fk.fkey
And ColR.id = TablaR.id And ColR.colid = fk.rkey
order by FKName
Set #vchForeign = ''
While Exists ( Select * From #tmpFK )
Begin
Select Top 1 #FKName = FKName From #tmpFK
Set #vchColumnasF = ''
Set #vchColumnasR = ''
While Exists ( Select * From #tmpFK Where FKName = #FKName )
Begin
Select Top 1 #ColF = ColF, #ColR = ColR, #TablaR = TablaR From #tmpFK Where FKName = #FKName
Delete From #tmpFK Where ColF = #ColF And ColR = #ColR And TablaR = #TablaR And FKName = #FKName
Set #vchColumnasF = #vchColumnasF + #ColF + ', '
Set #vchColumnasR = #vchColumnasR + #ColR + ', '
End
Set #vchColumnasF = LEFT(#vchColumnasF, LEN(#vchColumnasF) - 1)
Set #vchColumnasR = LEFT(#vchColumnasR, LEN(#vchColumnasR) - 1)
Set #vchTemp = 'Constraint ' + #FKName + ' Foreign Key (' + #vchColumnasF + ') '
Set #vchTemp = #vchTemp + 'References ' + #TablaR + ' (' + #vchColumnasR + ')'
Set #vchForeign = #vchForeign + char(9) + #vchTemp + ',' + char(13)
End
Select #vchResultado = Case When Len(#vchForeign) >=2 Then Left(#vchForeign, Len(#vchForeign) - 2) Else #vchForeign End
End
GO
Create Procedure sp_ppinScriptTabla
(
#vchTabla sysname
)
AS
Set nocount on
-- Obtengo las foreign keys
Declare #foreign varchar(8000)
Exec sp_ppinScriptLlavesForaneas #vchTabla, #foreign output
-- SELECT que devuelve el script de Create Table de la tabla
Select 'Create ' +
Case o.xtype When 'U' Then 'Table' When 'P' Then 'Procedure' Else '??' End + ' ' +
#vchTabla + char(13) + '('
From sysobjects o
Where o.name = #vchTabla
Union all
-- Campos + identitys + DEFAULTS
select char(9) + c.name + ' ' + -- Nombre
dbo.sp_ppinTipoLongitud(t.xtype, c.length, c.isnullable) + -- Tipo(longitud)
Case When c.colstat & 1 = 1 -- Identity (si aplica)
Then ' Identity(' + convert(varchar, ident_seed(#vchTabla)) + ',' + Convert(varchar, ident_incr(#vchTabla)) + ')'
Else ''
End +
Case When not od.name is null -- Defaults (si aplica)
Then ' Constraint ' + od.name + ' Default ' + replace(replace(cd.text, '((', '('), '))', ')')
Else ''
End + ', '
from sysobjects o, syscolumns c
LEFT OUTER JOIN sysobjects od On od.id = c.cdefault LEFT OUTER join syscomments cd On cd.id = od.id,
systypes t
where o.id = object_id(#vchTabla)
and o.id = c.id
and c.xtype = t.xtype
Union all
-- Primary Keys y Unique keys
select char(9) + 'Constraint ' + o.name + ' ' +
Case o.xtype When 'PK' Then 'Primary Key' Else 'Unique' End + ' ' +
dbo.sp_ppinCamposIndice (db_name(), #vchTabla, i.indid) + ', '
from sysobjects o, sysindexes i
where o.parent_obj = object_id(#vchTabla)
and o.xtype in ('PK','UQ')
and i.id = o.parent_obj
and o.name = i.name
Union all
-- Check constraints
select char(9) + 'Constraint ' + o.name + ' Check ' + c.text + ', '
from sysobjects o, syscomments c
where o.parent_obj = object_id(#vchTabla)
and o.xtype in ('C')
and o.id = c.id
Union all
-- Foreign keys
Select #foreign
Union all
Select ')'
Set nocount off
GO
Try sp_helptext Equivalent for Tables?
https://www.sqlservercentral.com/forums/topic/script-create-table-script-from-linked-server
For Linked Servers - on SQL Server - following works great -
SELECT *
INTO MyNewTable
FROM MyLinkedServer.DatabaseName.dbo.TargetTable
WHERE 1 = 0
--no data transferred, but the table gets built.
You forgot to include the stored procedure or function script for sp_ppinCamposIndice
Here's a slight variation on #Devart 's answer so you can get the CREATE script for a temp table.
Please note that since the #SQL variable is an NVARCHAR(MAX) data type you might not be able to copy it from the result using just only SSMS. Please see this question to see how to get the full value of a MAX field.
DECLARE #temptable_objectid INT = OBJECT_ID('tempdb..#Temp');
DECLARE
#object_name SYSNAME
, #object_id INT
SELECT
#object_name = '[' + s.name + '].[' + o.name + ']'
, #object_id = o.[object_id]
FROM tempdb.sys.objects o WITH (NOWAIT)
JOIN tempdb.sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE object_id = #temptable_objectid
DECLARE #SQL NVARCHAR(MAX) = ''
;WITH index_column AS
(
SELECT
ic.[object_id]
, ic.index_id
, ic.is_descending_key
, ic.is_included_column
, c.name
FROM tempdb.sys.index_columns ic WITH (NOWAIT)
JOIN tempdb.sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
WHERE ic.[object_id] = #object_id
),
fk_columns AS
(
SELECT
k.constraint_object_id
, cname = c.name
, rcname = rc.name
FROM tempdb.sys.foreign_key_columns k WITH (NOWAIT)
JOIN tempdb.sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id
JOIN tempdb.sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
WHERE k.parent_object_id = #object_id
)
SELECT #SQL = 'CREATE TABLE ' + #object_name + CHAR(13) + '(' + CHAR(13) + STUFF((
SELECT CHAR(9) + ', [' + c.name + '] ' +
CASE WHEN c.is_computed = 1
THEN 'AS ' + cc.[definition]
ELSE UPPER(tp.name) +
CASE WHEN tp.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')'
WHEN tp.name IN ('nvarchar', 'nchar', 'ntext')
THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(5)) END + ')'
WHEN tp.name IN ('datetime2', 'time2', 'datetimeoffset')
THEN '(' + CAST(c.scale AS VARCHAR(5)) + ')'
WHEN tp.name = 'decimal'
THEN '(' + CAST(c.[precision] AS VARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(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 dc.[definition] IS NOT NULL THEN ' DEFAULT' + dc.[definition] ELSE '' END +
CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(ic.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END
END + CHAR(13)
FROM tempdb.sys.columns c WITH (NOWAIT)
JOIN tempdb.sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
LEFT JOIN tempdb.sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
LEFT JOIN tempdb.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 tempdb.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] = #object_id
ORDER BY c.column_id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
+ ISNULL((SELECT CHAR(9) + ', CONSTRAINT [' + k.name + '] PRIMARY KEY (' +
(SELECT STUFF((
SELECT ', [' + c.name + '] ' + CASE WHEN ic.is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END
FROM tempdb.sys.index_columns ic WITH (NOWAIT)
JOIN tempdb.sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
WHERE ic.is_included_column = 0
AND ic.[object_id] = k.parent_object_id
AND ic.index_id = k.unique_index_id
FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ''))
+ ')' + CHAR(13)
FROM tempdb.sys.key_constraints k WITH (NOWAIT)
WHERE k.parent_object_id = #object_id
AND k.[type] = 'PK'), '') + ')' + CHAR(13)
+ ISNULL((SELECT (
SELECT CHAR(13) +
'ALTER TABLE ' + #object_name + ' WITH'
+ CASE WHEN fk.is_not_trusted = 1
THEN ' NOCHECK'
ELSE ' CHECK'
END +
' ADD CONSTRAINT [' + fk.name + '] FOREIGN KEY('
+ STUFF((
SELECT ', [' + k.cname + ']'
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
FOR XML PATH(''), TYPE).value('.', '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(''), TYPE).value('.', '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 ' + #object_name + ' CHECK CONSTRAINT [' + fk.name + ']' + CHAR(13)
FROM tempdb.sys.foreign_keys fk WITH (NOWAIT)
JOIN tempdb.sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
WHERE fk.parent_object_id = #object_id
FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)')), '')
+ ISNULL(((SELECT
CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END
+ ' NONCLUSTERED INDEX [' + i.name + '] ON ' + #object_name + ' (' +
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(''), TYPE).value('.', '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(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '') + CHAR(13)
FROM tempdb.sys.indexes i WITH (NOWAIT)
WHERE i.[object_id] = #object_id
AND i.is_primary_key = 0
AND i.[type] = 2
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
), '')
SELECT #SQL
Easiest way is to use the built-in feature of SQL Management Studio.
Right-click the database, go to tasks, Generate Scripts, and walk through the wizard. You can choose what objects to script, and it'll make it all for you.
Now if you are trying to make your OWN script to do the same thing, you're probably up for a lot of work...
Since we're offering alternatives to what you asked..
If you're in .Net, you should look at the Database Publishing Wizard in Visual Studio. Easy way to script your tables/data to a text file.
http://www.codeplex.com/sqlhost/Wiki/View.aspx?title=Database%20Publishing%20Wizard
Use the SSMS, easiest way
You can configure options for it as well (eg collation, syntax, drop...create)
Otherwise, SSMS Tools Pack, or DbFriend on CodePlex can help you generate scripts
See my answer in this Question : How to generate create script of table using SQL query in SQL Server
Use this query :
DROP FUNCTION [dbo].[Get_Table_Script]
Go
Create Function Get_Table_Script
(
#vsTableName varchar(50)
)
Returns
VarChar(Max)
With ENCRYPTION
Begin
Declare #ScriptCommand varchar(Max)
Select #ScriptCommand =
' Create Table [' + SO.name + '] (' + o.list + ')'
+
(
Case
When TC.Constraint_Name IS NULL
Then ''
Else 'ALTER TABLE ' + SO.Name + ' ADD CONSTRAINT ' +
TC.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')'
End
)
From sysobjects As SO
Cross Apply
(
Select
' [' + column_name + '] ' +
data_type +
(
Case data_type
When 'sql_variant'
Then ''
When 'text'
Then ''
When 'decimal'
Then '(' + Cast( numeric_precision_radix As varchar ) + ', ' + Cast( numeric_scale As varchar ) + ') '
Else Coalesce( '(' +
Case
When character_maximum_length = -1
Then 'MAX'
Else Cast( character_maximum_length As VarChar )
End + ')' , ''
)
End
)
+ ' ' +
(
Case
When Exists (
Select id
From syscolumns
Where
( object_name(id) = SO.name )
And
( name = column_name )
And
( columnproperty(id,name,'IsIdentity') = 1 )
)
Then 'IDENTITY(' +
Cast( ident_seed(SO.name) As varchar ) + ',' +
Cast( ident_incr(SO.name) As varchar ) + ')'
Else ''
End
) + ' ' +
(
Case
When IS_NULLABLE = 'No'
Then 'NOT '
Else ''
End
) + 'NULL ' +
(
Case
When information_schema.columns.COLUMN_DEFAULT IS NOT NULL
Then 'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT
ELse ''
End
) + ', '
From information_schema.columns
Where
( table_name = SO.name )
Order by ordinal_position
FOR XML PATH('')) o (list)
Inner Join information_schema.table_constraints As TC On (
( TC.Table_name = SO.Name )
AND
( TC.Constraint_Type = 'PRIMARY KEY' )
And
( TC.TABLE_NAME = #vsTableName )
)
Cross Apply
(
Select '[' + Column_Name + '], '
From information_schema.key_column_usage As kcu
Where
( kcu.Constraint_Name = TC.Constraint_Name )
Order By ORDINAL_POSITION
FOR XML PATH('')
) As j (list)
Where
( xtype = 'U' )
AND
( Name NOT IN ('dtproperties') )
Return #ScriptCommand
End
And you can fire this Function like this :
Select [dbo].Get_Table_Script '<Your_Table_Name>'
Try this (using "Results to text"):
SELECT
ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
FROM
sys.all_objects AS sp
LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
WHERE
(sp.type = N'V' OR sp.type = N'P' OR sp.type = N'RF' OR sp.type=N'PC')and(sp.name=N'YourObjectName' and SCHEMA_NAME(sp.schema_id)=N'dbo')
C: Check constraint
D: Default constraint
F: Foreign Key constraint
L: Log
P: Stored procedure
PK: Primary Key constraint
RF: Replication Filter stored procedure
S: System table
TR: Trigger
U: User table
UQ: Unique constraint
V: View
X: Extended stored procedure
Cheers,
we can let the SQL to generate create table script by navigating as
Script Table as > CREATE To > New Query Editor Window
#Devart : Thank you,The answer was perfect, I'm adding something which I found while coding.
#ildanny : Thank you for removing the word limitation
my inferences:
Added Default and Check constraints
Changed Identity :
varchar(max) from char(1) : some tables may start from large numbers
Triggers can also be added as they are part of table, the definition
is directly available from select object_id from sys.triggers'
.
.
.
CASE WHEN dc.[definition] IS NOT NULL THEN ' CONSTRAINT ' + quotename(dc.name) + ' DEFAULT' + dc.[definition] ELSE '' END +
CASE WHEN ck.[definition] IS NOT NULL THEN ' CONSTRAINT ' + quotename(ck.name) + ' CHECK' + ck.[definition] ELSE '' END +
CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS VARCHAR) + ',' + CAST(ISNULL(ic.increment_value, '1') AS VARCHAR) + ')' ELSE '' END
.
.
.
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.check_constraints ck WITH (NOWAIT) ON c.[object_id] = ck.parent_object_id AND c.column_id = ck.parent_column_id
.
.
.
Expanding on #Devart and #ildanny solutions...
I had the need to run this for ALL tables in a db and also to execute the code against Linked Servers.
All tables...
/*
Ex.
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'All', 0, NULL;
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'dbo', 0, NULL;
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'All', 1, '{linkedservername}';
*/
CREATE PROCEDURE etl.GetTableDefinitions
(
#SystemName NVARCHAR(128)
, #DatabaseName NVARCHAR(128)
, #SchemaName NVARCHAR(128)
, #linkedserver BIT
, #linkedservername NVARCHAR(128)
)
AS
DECLARE #sql NVARCHAR(MAX) = N'';
DECLARE #sql1 NVARCHAR(MAX) = N'';
DECLARE #inSchemaName NVARCHAR(MAX) = N'';
SELECT #inSchemaName = CASE WHEN #SchemaName = N'All' THEN N's.[name]' ELSE '''' + #SchemaName + '''' END;
IF #linkedserver = 0
BEGIN
SELECT #sql = N'
SET NOCOUNT ON;
--- options ---
DECLARE #UseTransaction BIT = 0;
DECLARE #GenerateUseDatabase BIT = 0;
DECLARE #GenerateFKs BIT = 0;
DECLARE #GenerateIdentity BIT = 1;
DECLARE #GenerateCollation BIT = 0;
DECLARE #GenerateCreateTable BIT = 1;
DECLARE #GenerateIndexes BIT = 0;
DECLARE #GenerateConstraints BIT = 1;
DECLARE #GenerateKeyConstraints BIT = 1;
DECLARE #GenerateConstraintNameOfDefaults BIT = 1;
DECLARE #GenerateDropIfItExists BIT = 0;
DECLARE #GenerateDropFKIfItExists BIT = 0;
DECLARE #GenerateDelete BIT = 0;
DECLARE #GenerateInsertInto BIT = 0;
DECLARE #GenerateIdentityInsert INT = 0; --0 ignore set,but add column; 1 generate; 2 ignore set AND column
DECLARE #GenerateSetNoCount INT = 0; --0 ignore set,1=set on, 2=set off
DECLARE #GenerateMessages BIT = 0; --print with no wait
DECLARE #GenerateDataCompressionOptions BIT = 0; --TODO: generates the compression option only of the TABLE, not the indexes
--NB: the compression options reflects the design VALUE.
--The actual compression of a the page is saved here
--- variables ---
DECLARE #DataTypeSpacer INT = 1; --this is just to improve the formatting of the script ...
DECLARE #name SYSNAME;
DECLARE #sql NVARCHAR(MAX) = N'''';
DECLARE #int INT = 1;
DECLARE #maxint INT;
DECLARE #SourceDatabase NVARCHAR(MAX) = N''' + #DatabaseName + '''; --this is used by the INSERT
DECLARE #TargetDatabase NVARCHAR(MAX) = N''' + #DatabaseName + '''; --this is used by the INSERT AND USE <DBName>
DECLARE #cr NVARCHAR(20) = NCHAR(13);
DECLARE #tab NVARCHAR(20) = NCHAR(9);
DECLARE #Tables TABLE
(
id INT IDENTITY(1,1)
, [name] SYSNAME
, [object_id] INT
, [database_id] SMALLINT
);
BEGIN
INSERT INTO #Tables([name], [object_id], [database_id])
SELECT s.[name] + N''.'' + t.[name] AS [name]
, t.[object_id]
, DB_ID(''' + #DatabaseName + ''') AS [database_id]
FROM [' + #DatabaseName + '].sys.tables t
JOIN [' + #DatabaseName + '].sys.schemas s ON t.[schema_id] = s.[schema_id]
WHERE t.[name] NOT IN (''Tally'',''LOC_AND_SEG_CAP1'',''LOC_AND_SEG_CAP2'',''LOC_AND_SEG_CAP3'',''LOC_AND_SEG_CAP4'',''TableNames'')
AND s.[name] = ' + #inSchemaName + '
ORDER BY s.[name], t.[name];
SELECT #maxint = COUNT(0)
FROM #Tables;
WHILE #int <= #maxint
BEGIN
;WITH
index_column AS
(
SELECT ic.[object_id]
, OBJECT_NAME(ic.[object_id], DB_ID(N''' + #DatabaseName + ''')) AS ObjectName
, ic.index_id
, ic.is_descending_key
, ic.is_included_column
, c.[name]
FROM [' + #DatabaseName + '].sys.index_columns ic WITH (NOLOCK)
JOIN [' + #DatabaseName + '].sys.columns c WITH (NOLOCK) ON ic.[object_id] = c.[object_id]
AND ic.column_id = c.column_id
JOIN [' + #DatabaseName + '].sys.tables t ON c.[object_id] = t.[object_id]
)
, fk_columns AS
(
SELECT k.constraint_object_id
, cname = c.[name]
, rcname = rc.[name]
FROM [' + #DatabaseName + '].sys.foreign_key_columns k WITH (NOWAIT)
JOIN [' + #DatabaseName + '].sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id
AND rc.column_id = k.referenced_column_id
JOIN [' + #DatabaseName + '].sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id
AND c.column_id = k.parent_column_id
JOIN [' + #DatabaseName + '].sys.tables t ON c.[object_id] = t.[object_id]
WHERE #GenerateFKs = 1
)
SELECT #sql = #sql +
-------------------- USE DATABASE --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #GenerateUseDatabase = 1
THEN N''USE '' + #TargetDatabase + N'';'' + #cr
ELSE N'''' END
AS NVARCHAR(200))
+
-------------------- SET NOCOUNT --------------------------------------------------------------------------------------------------
CAST(
CASE #GenerateSetNoCount
WHEN 1 THEN N''SET NOCOUNT ON;'' + #cr
WHEN 2 THEN N''SET NOCOUNT OFF;'' + #cr
ELSE N'''' END
AS NVARCHAR(MAX))
+
-------------------- USE TRANSACTION --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #UseTransaction = 1
THEN
N''SET XACT_ABORT ON'' + #cr
+ N''BEGIN TRY'' + #cr
+ N''BEGIN TRAN'' + #cr
ELSE N'''' END
AS NVARCHAR(MAX))
+
-------------------- DROP SYNONYM --------------------------------------------------------------------------------------------------
CASE WHEN #GenerateDropIfItExists = 1
THEN CAST(N''IF OBJECT_ID('''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''',''''SN'''') IS NOT NULL DROP SYNONYM '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + #cr AS NVARCHAR(MAX))
ELSE CAST(N'''' AS NVARCHAR(MAX)) END
+
-------------------- DROP TABLE IF EXISTS --------------------------------------------------------------------------------------------------
CASE WHEN #GenerateDropIfItExists = 1
THEN
--Drop TABLE if EXISTS
CAST(N''IF OBJECT_ID('''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''',''''U'''') IS NOT NULL DROP TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + #cr AS NVARCHAR(MAX))
+ #cr
ELSE N'''' END
+
-------------------- DROP CONSTRAINT IF EXISTS --------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 AND #GenerateDropFKIfItExists = 1 THEN
N''RAISERROR(''''DROP CONSTRAINTS OF %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE N'''' END) AS NVARCHAR(MAX))
+
CASE WHEN #GenerateDropFKIfItExists = 1
THEN
--Drop foreign keys
ISNULL(((
SELECT
CAST(
N''ALTER TABLE '' + QUOTENAME(s.[name]) + N''.'' + QUOTENAME(t.[name]) + N'' DROP CONSTRAINT '' + RTRIM(f.[name]) + N'';'' + #cr
AS NVARCHAR(MAX))
FROM [' + #DatabaseName + '].sys.tables t
INNER JOIN [' + #DatabaseName + '].sys.foreign_keys f ON f.parent_object_id = t.[object_id]
INNER JOIN [' + #DatabaseName + '].sys.schemas s ON s.[schema_id] = f.[schema_id]
WHERE f.referenced_object_id = t.[object_id]
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''))
, N'''') + #cr
ELSE N'''' END
+
--------------------- CREATE TABLE -----------------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 THEN
N''RAISERROR(''''CREATE TABLE %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE CAST(N'''' AS NVARCHAR(MAX)) END) AS NVARCHAR(MAX))
+
CASE WHEN #GenerateCreateTable = 1 THEN
CAST(
N''CREATE TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + #cr + N''('' + #cr + STUFF((
SELECT
CAST(
#tab + N'','' + QUOTENAME(c.[name]) + N'' '' + ISNULL(REPLICATE('' '',#DataTypeSpacer - LEN(QUOTENAME(c.[name]))),'''')
+
CASE WHEN c.is_computed = 1
THEN N'' AS '' + cc.[definition]
ELSE UPPER(tp.[name]) +
CASE WHEN tp.[name] IN (N''varchar'', N''char'', N''varbinary'', N''binary'', N''text'')
THEN N''('' + CASE WHEN c.max_length = -1 THEN N''MAX'' ELSE CAST(c.max_length AS NVARCHAR(5)) END + N'')''
WHEN tp.[name] IN (N''NVARCHAR'', N''nchar'', N''ntext'')
THEN N''('' + CASE WHEN c.max_length = -1 THEN N''MAX'' ELSE CAST(c.max_length / 2 AS NVARCHAR(5)) END + N'')''
WHEN tp.[name] IN (N''datetime2'', N''time2'', N''datetimeoffset'')
THEN N''('' + CAST(c.scale AS NVARCHAR(5)) + N'')''
WHEN tp.[name] = N''decimal''
THEN N''('' + CAST(c.[precision] AS NVARCHAR(5)) + N'','' + CAST(c.scale AS NVARCHAR(5)) + N'')''
ELSE N''''
END +
CASE WHEN c.collation_name IS NOT NULL AND #GenerateCollation = 1 THEN N'' COLLATE '' + c.collation_name ELSE N'''' END +
CASE WHEN c.is_nullable = 1 THEN N'' NULL'' ELSE N'' NOT NULL'' END +
CASE WHEN dc.[definition] IS NOT NULL THEN CASE WHEN #GenerateConstraintNameOfDefaults = 1 THEN N'' CONSTRAINT '' + QUOTENAME(dc.[name]) ELSE N'''' END + N'' DEFAULT'' + dc.[definition] ELSE N'''' END +
CASE WHEN ic.is_identity = 1 AND #GenerateIdentity = 1 THEN N'' IDENTITY('' + CAST(ISNULL(ic.seed_value, N''0'') AS NCHAR(1)) + N'','' + CAST(ISNULL(ic.increment_value, N''1'') AS NCHAR(1)) + N'')'' ELSE N'''' END
END + #cr
AS NVARCHAR(MAX))
FROM [' + #DatabaseName + '].sys.columns c WITH (NOWAIT)
INNER JOIN [' + #DatabaseName + '].sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
LEFT JOIN [' + #DatabaseName + '].sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id]
AND c.column_id = cc.column_id
LEFT JOIN [' + #DatabaseName + '].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 [' + #DatabaseName + '].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] = t.[object_id]
ORDER BY c.column_id
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, #tab + N'' '') AS NVARCHAR(MAX))
ELSE CAST(N'''' AS NVARCHAR(MAX)) END
+
---------------------- Key Constraints ----------------------------------------------------------------
CAST(
CASE WHEN #GenerateKeyConstraints <> 1 THEN N''''
ELSE
ISNULL((SELECT #tab + N'', CONSTRAINT '' + QUOTENAME(k.[name]) + N'' PRIMARY KEY '' + ISNULL(kidx.[type_desc], N'''') + N''('' +
(SELECT STUFF((
SELECT N'', '' + QUOTENAME(c.[name]) + N'' '' + CASE WHEN ic.is_descending_key = 1 THEN N''DESC'' ELSE N''ASC'' END
FROM [' + #DatabaseName + '].sys.index_columns ic WITH (NOWAIT)
JOIN [' + #DatabaseName + '].sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id]
AND c.column_id = ic.column_id
WHERE ic.is_included_column = 0
AND ic.[object_id] = k.parent_object_id
AND ic.index_id = k.unique_index_id
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N''''))
+ N'')'' + #cr
FROM [' + #DatabaseName + '].sys.key_constraints k WITH (NOWAIT)
LEFT JOIN [' + #DatabaseName + '].sys.indexes kidx ON k.parent_object_id = kidx.[object_id]
AND k.unique_index_id = kidx.index_id
WHERE k.parent_object_id = t.[object_id]
AND k.[type] = N''PK''), N'''') + N'')'' + #cr
END
AS NVARCHAR(MAX))
+
CAST(
CASE
WHEN #GenerateDataCompressionOptions = 1 AND (SELECT TOP 1 data_compression_desc FROM [' + #DatabaseName + '].sys.partitions WHERE OBJECT_ID = t.[object_id] AND index_id = 1) <> N''NONE''
THEN N''WITH (DATA_COMPRESSION='' + (SELECT TOP 1 data_compression_desc FROM [' + #DatabaseName + '].sys.partitions WHERE OBJECT_ID = t.[object_id] AND index_id = 1) + N'')'' + #cr
ELSE N'''' + #cr
END AS NVARCHAR(MAX))
+
--------------------- FOREIGN KEYS -----------------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 AND #GenerateDropFKIfItExists = 1 THEN
N''RAISERROR(''''CREATING FK OF %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE N'''' END) AS NVARCHAR(MAX))
+
CAST(
ISNULL((SELECT (
SELECT #cr +
N''ALTER TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' WITH''
+ CASE WHEN fk.is_not_trusted = 1
THEN N'' NOCHECK''
ELSE N'' CHECK''
END +
N'' ADD CONSTRAINT '' + QUOTENAME(fk.[name]) + N'' FOREIGN KEY(''
+ STUFF((
SELECT N'', '' + QUOTENAME(k.cname) + N''''
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
AND fk.[object_id] = t.[object_id]
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N'''')
+ N'')'' +
N'' REFERENCES '' + QUOTENAME(SCHEMA_NAME(ro.[schema_id])) + N''.'' + QUOTENAME(ro.[name]) + N'' (''
+ STUFF((
SELECT N'', '' + QUOTENAME(k.rcname) + N''''
FROM fk_columns k
WHERE k.constraint_object_id = fk.[object_id]
AND fk.[object_id] = t.[object_id]
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N'''')
+ N'')''
+ CASE
WHEN fk.delete_referential_action = 1 THEN N'' ON DELETE CASCADE''
WHEN fk.delete_referential_action = 2 THEN N'' ON DELETE SET NULL''
WHEN fk.delete_referential_action = 3 THEN N'' ON DELETE SET DEFAULT''
ELSE N''''
END
+ CASE
WHEN fk.update_referential_action = 1 THEN N'' ON UPDATE CASCADE''
WHEN fk.update_referential_action = 2 THEN N'' ON UPDATE SET NULL''
WHEN fk.update_referential_action = 3 THEN N'' ON UPDATE SET DEFAULT''
ELSE N''''
END
+ #cr + N''ALTER TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' CHECK CONSTRAINT '' + QUOTENAME(fk.[name]) + N'''' + #cr
FROM [' + #DatabaseName + '].sys.foreign_keys fk WITH (NOWAIT)
JOIN [' + #DatabaseName + '].sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
WHERE fk.parent_object_id = t.[object_id]
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')), N'''')
AS NVARCHAR(MAX))
+
--------------------- INDEXES ----------------------------------------------------------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 AND #GenerateIndexes = 1 THEN
N''RAISERROR(''''CREATING INDEXES OF %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE N'''' END) AS NVARCHAR(MAX))
+
CASE WHEN #GenerateIndexes = 1 THEN
CAST(
ISNULL(((SELECT
#cr + N''CREATE'' + CASE WHEN i.is_unique = 1 THEN N'' UNIQUE '' ELSE N'' '' END
+ i.[type_desc] + N'' INDEX '' + QUOTENAME(i.[name]) + N'' ON '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' ('' +
STUFF((
SELECT N'', '' + QUOTENAME(c.[name]) + N'''' + CASE WHEN c.is_descending_key = 1 THEN N'' DESC'' ELSE N'' ASC'' END
FROM index_column c
WHERE c.is_included_column = 0
AND c.[object_id] = t.[object_id]
AND c.index_id = i.index_id
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N'''') + N'')''
+ ISNULL(#cr + N''INCLUDE ('' +
STUFF((
SELECT N'', '' + QUOTENAME(c.[name]) + N''''
FROM index_column c
WHERE c.is_included_column = 1
AND c.[object_id] = t.[object_id]
AND c.index_id = i.index_id
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N'''') + N'')'', N'''') + #cr
FROM [' + #DatabaseName + '].sys.indexes i WITH (NOWAIT)
WHERE i.[object_id] = t.[object_id]
AND i.is_primary_key = 0
AND i.[type] in (1,2)
AND #GenerateIndexes = 1
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')
), N'''')
AS NVARCHAR(MAX))
ELSE N'''' END
+
------------------------ #GenerateDelete ----------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 AND #GenerateDelete = 1 THEN
N''RAISERROR(''''TRUNCATING %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE N'''' END) AS NVARCHAR(MAX))
+
CASE WHEN #GenerateDelete = 1 THEN
CAST(
(CASE WHEN EXISTS (SELECT TOP 1 [name] FROM [' + #DatabaseName + '].sys.foreign_keys WHERE referenced_object_id = t.[object_id]) THEN
N''DELETE FROM '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + #cr
ELSE
N''TRUNCATE TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + #cr
END)
AS NVARCHAR(MAX))
ELSE N'''' END
+
------------------------- #GenerateInsertInto ----------------------------------------------------------
CAST((CASE WHEN #GenerateMessages = 1 AND #GenerateDropFKIfItExists = 1 THEN
N''RAISERROR(''''INSERTING INTO %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + #cr
ELSE N'''' END) AS NVARCHAR(MAX))
+
CASE WHEN #GenerateInsertInto = 1
THEN
CAST(
CASE WHEN EXISTS (SELECT TOP 1 c.[name] FROM [' + #DatabaseName + '].sys.columns c WHERE c.[object_id] = t.[object_id] AND c.is_identity = 1) AND #GenerateIdentityInsert = 1 THEN
N''SET IDENTITY_INSERT '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' ON;'' + #cr
ELSE N'''' END
+
N''INSERT INTO '' + QUOTENAME(#TargetDatabase) + N''.'' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N''(''
+ #cr
+
(
#tab + N'' '' + SUBSTRING(
(
SELECT #tab + '',''+ QUOTENAME(c.[name]) + #cr
FROM [' + #DatabaseName + '].sys.columns c
WHERE c.[object_id] = t.[object_id]
AND c.system_type_ID <> 189 /*timestamp*/
AND c.is_computed = 0
AND (c.is_identity = 0 or #GenerateIdentityInsert in (0,1))
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')
,3,99999)
)
+ N'')'' + #cr + N''SELECT ''
+ #cr
+
(
#tab + N'' '' + SUBSTRING(
(
SELECT #tab + '',''+ QUOTENAME(c.[name]) + #cr
FROM [' + #DatabaseName + '].sys.columns c
WHERE c.[object_id] = t.[object_id]
AND c.system_type_ID <> 189 /*timestamp*/
AND c.is_computed = 0
AND (c.is_identity = 0 or #GenerateIdentityInsert in (0,1))
FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')
,3,99999)
)
+ N''FROM '' + #SourceDatabase + N''.'' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id]))
+ N'';'' + #cr
+ CASE WHEN EXISTS (SELECT TOP 1 c.[name] FROM [' + #DatabaseName + '].sys.columns c WHERE c.[object_id] = t.[object_id] AND c.is_identity = 1) AND #GenerateIdentityInsert = 1 THEN
N''SET IDENTITY_INSERT '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' OFF;''+ #cr
ELSE N'''' END
AS NVARCHAR(MAX))
ELSE N'''' END
+
-------------------- USE TRANSACTION --------------------------------------------------------------------------------------------------
CAST(
CASE WHEN #UseTransaction = 1
THEN
#cr + N''COMMIT TRAN; ''
+ #cr + N''END TRY''
+ #cr + N''BEGIN CATCH''
+ #cr + N'' IF XACT_STATE() IN (-1,1)''
+ #cr + N'' ROLLBACK TRAN;''
+ #cr + N''''
+ #cr + N'' SELECT ERROR_NUMBER() AS ErrorNumber ''
+ #cr + N'' ,ERROR_SEVERITY() AS ErrorSeverity ''
+ #cr + N'' ,ERROR_STATE() AS ErrorState ''
+ #cr + N'' ,ERROR_PROCEDURE() AS ErrorProcedure ''
+ #cr + N'' ,ERROR_LINE() AS ErrorLine ''
+ #cr + N'' ,ERROR_MESSAGE() AS ErrorMessage; ''
+ #cr + N''END CATCH''
ELSE N'''' END
AS NVARCHAR(700))
FROM #Tables t
WHERE ID = #int
ORDER BY [name];
SET #int = #int + 1;
END
EXEC [master].dbo.PrintMax #sql;
/* see below for PrintMax code*/
END'
EXEC (#sql);
END
ELSE
And the Linked Server bit...
BEGIN
SELECT #sql = N'EXECUTE (''
SET NOCOUNT ON;
BEGIN
... Same code but be sure to double up on your single quotes
END
... code for the printmax proc (not mine, #Ben B) because it may not exist at destination server
DECLARE #CurrentEnd BIGINT; /* track the length of the next substring */
DECLARE #offset TINYINT; /*tracks the amount of offset needed */
DECLARE #String NVARCHAR(MAX);
SET #String = REPLACE(REPLACE(#sql, CHAR(13) + CHAR(10), CHAR(10)), CHAR(13), CHAR(10))
WHILE LEN(#String) > 1
BEGIN
IF CHARINDEX(CHAR(10), #String) BETWEEN 1 AND 4000
BEGIN
SET #CurrentEnd = CHARINDEX(CHAR(10), #String) -1
SET #offset = 2
END
ELSE
BEGIN
SET #CurrentEnd = 4000
SET #offset = 1
END
PRINT SUBSTRING(#String, 1, #CurrentEnd)
SET #String = SUBSTRING(#String, #CurrentEnd + #offset, LEN(#String))
END
END'') AT [' + #linkedservername + ']';
EXEC (#sql);
END
Ben B solution