Update/ replace value of extended property using T-SQL - sql-server

I have around 500 columns and I want to update their extended property value using T-SQL. Basically value has | (pipe) in it and I want to replace all | with CHAR(13) + CHAR(10).
For testing I'm trying to update one value using below code and I'm getting this error
Ad hoc updates to system catalogs are not allowed.
UPDATE p
SET p.value = REPLACE(p.value, '|', CHAR(13) + CHAR(10))
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns
ON clmns.object_id = tbl.object_id
INNER JOIN sys.extended_properties AS p
ON p.major_id = tbl.object_id
AND p.minor_id = clmns.column_id
AND p.class = 1
WHERE SCHEMA_NAME(tbl.schema_id) = 'dbo'
AND tbl.name = 'ACXM_HHLD'
AND clmns.name = 'Business_Owner';

That was trickier as I thought with NVARCHAR(MAX) that cannot be converted into SQL_VARIANT and stored procedures that don't accept inline CAST expressions...
But this here should do the trick, replacing all | in all column descriptions through CrLf.
DECLARE #TSQL NVARCHAR(MAX) = 'DECLARE #Text AS NVARCHAR(4000);' + CHAR(13) + CHAR(10) + 'DECLARE #Variant AS SQL_VARIANT;' + CHAR(13) + CHAR(10);
WITH Description ([Schema], [Table], [Column], [Text]) AS (
SELECT SCHEMA_NAME(schema_id), tbl.name, clmns.name, CAST(p.value AS NVARCHAR(MAX))
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns ON clmns.object_id = tbl.object_id
INNER JOIN sys.extended_properties AS p ON p.major_id = tbl.object_id AND p.minor_id = clmns.column_id AND p.Name = 'MS_Description' AND p.class = 1
)
SELECT #TSQL = #TSQL +
N'SET #Text = ''' + REPLACE(REPLACE([Text], '''', ''''''), '|', CHAR(13) + CHAR(10)) + ''';' + CHAR(13) + CHAR(10) +
N'SET #Variant = #Text;' + CHAR(13) + CHAR(10) +
N'EXEC sp_updateextendedproperty N''MS_Description'', #Variant, N''SCHEMA'', ''' + REPLACE([Schema], '''', '''''') + ''', N''TABLE'', ''' + REPLACE([Table], '''', '''''') + ''', N''COLUMN'', ''' + REPLACE([Column], '''', '''''') + '''' + CHAR(13) + CHAR(10)
FROM Description
EXEC sp_executesql #TSQL

Related

Dump SQL Server database schema with `sqlcmd` [duplicate]

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

How to run a .sql file using bcp in SQL Server

I am new to handling SQL Server bulk export. I have a batch file in which I have written some code to execute specific .sql files at regular intervals and save the output into an excel sheet. I have done this using sqlcmd. I want to use bcp to do the same. Any help on this issue is much appreciated.
use -s "|" with sqlcmd. That should allow you to out-put the data with fields separated by a tab.
-s is for column separator.
See sqlcmd Utility
Hafsa Mushtaq.
The best option is powershell - you can use this awesome dbatools function to Import your data https://github.com/sqlcollaborative/dbatools/blob/development/functions/Import-DbaCsvToSql.ps1 and my script to Export https://github.com/ktaranov/sqlserver-kit/blob/master/PowerShell/Export-SQLTableToCSV.ps1
Or you can use dynamic sql to generate all statements and then execute it.
All stored procedures below needed to solve some limitation of bcp and BULK INSERT in SQL Server - bcp can not create files with header and BULK INSERT can not import in tables with IDENTITY column.
To unload all tables to csv using bcp utility and my stored procedures usp_bcpTableUnload and usp_PrintString:
DECLARE #tsqlCommand NVARCHAR(MAX) = '';
DECLARE #path NVARCHAR(900) = 'd:\111\NIIGAZ\333\';
DECLARE #databaseName SYSNAME = 'NIIGAZ';
DECLARE #exludeColumns NVARCHAR(MAX) = ''; -- '[CreatedDate],[ModifiedDate],[UserID]';
DECLARE #codePage NVARCHAR(10) ='C65001'; -- '1251'
DECLARE #crlf NVARCHAR(10) = CHAR(13);
DECLARE #debug BIT = 1;
IF #debug = 0 SET NOCOUNT ON;
SELECT #tsqlCommand = #tsqlCommand + 'EXECUTE dbo.usp_bcpTableUnload #databaseName = ''' + #databaseName + ''',' + #crlf +
' #path = ''' + #path + ''',' + #crlf +
' #schemaName = ''' + SCHEMA_NAME(t.[schema_id]) + ''',' + #crlf +
' #tableName = ''' + t.[name] + ''',' + #crlf +
' #excludeColumns = ''' + #exludeColumns + ''',' + #crlf +
' #codePage = ''' + #codePage + ''',' + #crlf +
' #formatFile = ''xml'';' + #crlf
FROM [sys].[tables] t
INNER JOIN [sys].[dm_db_partition_stats] ps
ON ps.[object_id] = t.[object_id]
WHERE [index_id] < 2 -- AND SCHEMA_NAME(t.[schema_id]) IN ()
GROUP BY t.[name]
,t.[schema_id]
HAVING SUM(ps.[row_count]) > 1
--ORDER BY 1, 2 ASC
OPTION (RECOMPILE);
IF #debug = 1
BEGIN
EXEC dbo.usp_PrintString #str = #tsqlCommand;
END;
IF #debug = 0
BEGIN
EXEC sp_executesql #tsqlCommand;
END
And to bulk insert this files in database you can use this code and stored procedure usp_BulkUpload:
DECLARE #debug BIT = 0;
DECLARE #tsqlCommand NVARCHAR(max) = '';
DECLARE #path NVARCHAR(1000) = '$(varPath)txt\'; -- 'd:\NII\SQL\txt\';
DECLARE #ExcludeColumns NVARCHAR(1000) = ''; -- 'CreatedDate,ModifiedDate,UserID';
DECLARE #firstRow INTEGER = 2;
DECLARE #fieldTerminator NVARCHAR(10) = '''|''';
DECLARE #crlf NVARCHAR(10) = CHAR(13);
WITH fk_tables AS (
SELECT s1.name AS from_schema
, o1.name AS from_table
, s2.name AS to_schema
, o2.name AS to_table
FROM sys.foreign_keys fk
INNER JOIN sys.objects o1 ON fk.parent_object_id = o1.object_id
INNER JOIN sys.schemas s1 ON o1.schema_id = s1.schema_id
INNER JOIN sys.objects o2 ON fk.referenced_object_id = o2.object_id
INNER JOIN sys.schemas s2 ON o2.schema_id = s2.schema_id
/*For the purposes of finding dependency hierarchy
we're not worried about self-referencing tables*/
WHERE NOT (s1.name = s2.name
AND o1.name = o2.name
)
)
, ordered_tables AS (
SELECT s.name AS schemaName
, t.name AS tableName
, 0 AS table_level
FROM sys.tables AS t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
LEFT JOIN fk_tables fk ON s.name = fk.from_schema
AND t.name = fk.from_table
WHERE fk.from_schema IS NULL
UNION ALL
SELECT fk.from_schema
,fk.from_table
,ot.table_level + 1
FROM fk_tables fk
INNER JOIN ordered_tables ot ON fk.to_schema = ot.schemaName
AND fk.to_table = ot.tableName
)
,final AS (
SELECT DISTINCT ot.schemaName
,ot.tableName
,ot.table_level
FROM ordered_tables ot
INNER JOIN (
SELECT schemaName
,tableName
,MAX(table_level) maxLevel
FROM ordered_tables
GROUP BY schemaName
,tableName
) mx ON ot.schemaName = mx.schemaName
AND ot.tableName = mx.tableName
AND mx.maxLevel = ot.table_level
)
SELECT #tsqlCommand = #tsqlCommand +
'EXECUTE dbo.usp_BulkUpload #path = ''' + #path + ''', ' + #crlf +
' #fileName = ''' + QUOTENAME(final.schemaName) + '.' + QUOTENAME(final.tableName) + ''', ' + #crlf +
' #fileExtension = ''txt'', ' + #crlf +
' #databaseName = ''NIIGAZ'', ' + #crlf +
' #schemaName = ''' + final.schemaName + ''', ' + #crlf +
' #tableName = ''' + final.tableName + ''', ' + #crlf +
' #FIRSTROW = ' + CAST(#firstRow AS NVARCHAR) + ',' + #crlf +
' #CODEPAGE = ' + N'65001' + ' ,' + #crlf +
' #useIdentity = ' + CASE WHEN OBJECTPROPERTY(OBJECT_ID(schemaName + '.' + tableName), 'TableHasIdentity') = 1
THEN '1' ELSE '0'
END + ' ,' + #crlf +
' #FIELDTERMINATOR = ' + #fieldTerminator + ',' + #crlf +
' #ROWTERMINATOR = ''' + CASE WHEN final.tableName IN ('PowerPlant', 'Turbine', 'EnergoBusinessArticle') THEN N'0x0a'''
ELSE '\n'''
END + ' ,' + #crlf +
' #excludeColumns = ''' + #ExcludeColumns + ''';' + #crlf
FROM final
WHERE (
final.schemaName NOT IN ('dbo')
AND final.tableName NOT IN (
'ExcludeYourTable'
)
AND final.tableName NOT LIKE '%Temp'
)
OR final.tableName IN ('IncludeYourTable')
OR final.tableName LIKE 'AspNet%'
OR final.tableName LIKE 'Application%'
ORDER BY table_level;
IF #debug = 1 EXECUTE dbo.usp_PrintString #str = #tsqlCommand;
IF #debug = 0 EXECUTE sp_executesql #tsqlCommand;

UPDATE all tables on a database

I'm working on updating all the tables on a DB and I am having trouble getting the code correct. I was given the below code but as a previous solution but I am trying to use the SP_msforeachtable and can't get the correct format. And help with this would be wonderful. Here is the code:
USE TPP_DB
GO
DECLARE #SQL NVARCHAR(MAX)
EXEC sp_MSforeachtable
'SELECT #SQL = (
SELECT ''
UPDATE ''' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + ''.'''' + QUOTENAME(o.name) + '''
SET ''' + QUOTENAME(c.name) + '' = NULL
WHERE '' + QUOTENAME(c.name) + '' = '''''
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT #SQL
EXEC sys.sp_executesql #SQL'
You can try like this,
SELECT 'UPDATE ' + Schema_name(t.schema_id) + '.'
+ t.NAME + ' SET ' + c.NAME + ' =NULL WHERE ' + c.NAME
+ ' ='''';'
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
--WHERE c.NAME = 'ModifiedDate'
ORDER BY Schema_name(t.schema_id),
t.NAME;

Compare 2 rows in MS SQL and get the columns that differ

i have searched this one out for a while, but just don't know if there is a "silver bullet" solution to what I'm looking to do. I have a table in my DB (for the sake of this discussion the actual columns are irrelevant). I want to be able to look at 2 rows from the same table and get a list of columns that are different between the 2.
I know I could write a whole bunch of TSQL to make this happen for a specific table, but I was hoping there was a built in function in SQL Server (I'm running 2008 R2) that could do this.
I know there are simple functions like CHECKSUM that will tell me if 2 rows are different, but I need the specifics of which columns are different.
Preferably I would like to make it into a UDF and pass the table name, and primary keys of the 2 rows I want compared.
Any Thoughts or Suggestions?
--EDIT-- Here is the solution I came up with:
Well, It is certainly not the most elegant solution...but it will work in a pinch.
CREATE PROCEDURE sp_Compare_Table_Rows
(
#TablePK varchar(1000), -- The Name of the Primary Key in that Table
#TableName varchar(1000), -- The Name of the Table
#PK1 int, -- The ID of the 1st table
#PK2 int -- The ID of the 2nd table
)
AS
DECLARE #Holder table
(
Column_Name varchar(250),
Different bit
)
INSERT INTO #Holder(Column_Name,Different)
select
COLUMN_NAME,0
from
LPS_DEV.INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = #TableName
and ORDINAL_POSITION >1
DECLARE #LoopedColumnName varchar(250)
DECLARE #DynamicQuery nvarchar(max)
DECLARE #ORD1 int
DECLARE #ORD2 int
SET #DynamicQuery = ''
SET #LoopedColumnName = ''
SET #ORD1 = 0
SET #ORD2 = 0
DECLARE MYCUR CURSOR FOR SELECT Column_Name FROM #Holder
OPEN MYCUR
FETCH NEXT FROM MYCUR INTO #LoopedColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #DynamicQuery = 'SELECT #Outer= CHECKSUM(' + #LoopedColumnName + ') FROM ' + #TableName + ' WHERE ' + #TablePK + ' = ' + CONVERT(varchar(100),#PK1)
exec sp_executesql #DynamicQuery, N'#Outer int output',#ORD1 out
SET #DynamicQuery = 'SELECT #Outer= CHECKSUM(' + #LoopedColumnName + ') FROM ' + #TableName + ' WHERE ' + #TablePK + ' = ' + CONVERT(varchar(100),#PK2)
exec sp_executesql #DynamicQuery, N'#Outer int output',#ORD2 out
IF #ORD1 <> #ORD2
BEGIN
UPDATE #Holder SET Different = 1 WHERE Column_Name = #LoopedColumnName
END
FETCH NEXT FROM MYCUR INTO #LoopedColumnName
END
CLOSE MYCUR
DEALLOCATE MYCUR
select * from #Holder
John, you can use something like this. This will display the column names -
Set the #tablename and #whereclause.
declare #tablename varchar(1000),
#cols varchar(max),
#sqlstmt nvarchar(max),
#whereclause nvarchar(max);
set #tablename = 'sometable';
set #whereclause = ' where
a.col1 = ''SOMEOTHERVALUE'' and a.datecol2 = ''19910101'' and
b.col2 = ''SOMEVALUE'' and b.datecol2 = ''19910101''
'
select #cols = stuff((
select ', case when a.' + c.name + ' = b.' + c.name
+ ' then '''' else ''' + c.name + ''' end'
from sys.columns c
inner join sys.tables t on c.object_id = t.object_id
where t.name = #tablename
for xml path ('')), 1, 1, '')
set #sqlstmt = 'select ' + #cols + ' from ' + #tablename
+ ' a, ' + #tablename + ' b ' + #whereclause
exec sp_executesql #sqlstmt
I did some enhancements on Sriram answer, here is the new script:
declare #tablename nvarchar(MAX),
#cols varchar(max) = '',
#sqlstmt nvarchar(max) = 'DECLARE #T AS TABLE (ColumnName NVARCHAR(MAX), Value NVARCHAR(MAX), Value2 NVARCHAR(MAX))',
#whereclause nvarchar(max) = '';
set #tablename = 'TABLE_NAME';
set #whereclause = ' where a.FIRST_ROW_ID = ''NUMBER'' and b.SECOND_ROW_ID = ''NUMBER'''
select #cols = (
select ' INSERT INTO #T SELECT ''' + c.name + ''', cast(a.' + c.name + ' as nvarchar(max)), cast(b.' + c.name + ' as nvarchar(max)) from ' + #tablename + ' a, ' + #tablename + ' b ' + #whereclause + ' AND cast(a.' + c.name + ' as nvarchar(max)) != cast(b.' + c.name + ' as nvarchar(max))'
from sys.columns c
inner join sys.tables t on c.object_id = t.object_id
where t.name = #tablename
for xml path (''))
set #sqlstmt += #cols + ' SELECT * FROM #T'
exec sp_executesql #sqlstmt
You need to replace 'TABLE_NAME' with your table and change the where clause variable.
The result will be like this:
ColumnName | Value | Value2
----------------------------
Id | 1 | 2
Name | Name 1 | Name 2
I have done further enhancement to Sriram Chitturi and Mohamed Noor's answer and also handled datetime comparison
ALTER PROC [dbo].[IdentifyNotMatchingColumnDataBetween2Rows] (
#table_name VARCHAR(300) = 'TableName'
,#excluded_columns VARCHAR(300) = 'Id,UpdateTimeStamp,InsertTimeStamp,IsDuplicate,NotMatchingColumns'
,#compare_row_id_1 INT = 1732340
,#compare_row_id_2 INT = 1736803
)
AS
/*
EXEC [dbo].[IdentifyNotMatchingColumnDataBetween2Rows]
*/
BEGIN
SET NOCOUNT ON;
DECLARE #cols VARCHAR(max) = ''
DECLARE #sqlstmt NVARCHAR(max) = 'DECLARE #T AS TABLE (ColumnName VARCHAR(300), Value NVARCHAR(MAX), Value2 NVARCHAR(MAX))'
DECLARE #where_clause NVARCHAR(max) = ' WHERE a.Id = ''' + CAST(#compare_row_id_1 as varchar(20)) + ''' and b.Id = ''' + CAST(#compare_row_id_2 as varchar(20)) + ''''
SELECT #cols = (
SELECT CASE
WHEN c.system_type_id = 106 --DECIMAL
OR c.system_type_id = 56 --INT
OR c.system_type_id = 48 --TINYINT
OR c.system_type_id = 52 --SMALLINT
OR c.system_type_id = 127 --BIGINT
OR c.system_type_id = 62 --FLOAT
OR c.system_type_id = 108 --NUMERIC
THEN ' INSERT INTO #T SELECT ''[' + c.name + ']'', CAST(a.[' + c.name + '] AS NVARCHAR(MAX)), CAST(b.[' + c.name + '] AS NVARCHAR(MAX)) FROM [' + #table_name + '] a WITH(NOLOCK) , [' + #table_name + '] b WITH(NOLOCK) ' + #where_clause + ' AND CAST(ISNULL(a.[' + c.name + '],' + '-1' + ') AS NVARCHAR(MAX)) != CAST(ISNULL(b.[' + c.name + '],' + '-1' + ') AS NVARCHAR(MAX))'
WHEN c.system_type_id IN (61,42) -- DATETIME / DATETIME2
THEN ' INSERT INTO #T SELECT ''[' + c.name + ']'', FORMAT(a.[' + c.name + '] ,''yyyyMMddHHmmssffff''), FORMAT(b.[' + c.name + '] ,''yyyyMMddHHmmssffff'') FROM [' + #table_name + '] a WITH(NOLOCK) , [' + #table_name + '] b WITH(NOLOCK) ' + #where_clause + ' AND FORMAT(ISNULL(a.[' + c.name + '],' + '''' + '1900-01-01' + '''' + ') ,''yyyyMMddHHmmssffff'') != FORMAT(ISNULL(b.[' + c.name + '],' + '''' + '1900-01-01' + '''' + ') ,''yyyyMMddHHmmssffff'')'
WHEN c.system_type_id = 58 --SMALLDATETIME
THEN ' INSERT INTO #T SELECT ''[' + c.name + ']'', FORMAT(a.[' + c.name + '] ,''yyyyMMddHHmmss''), FORMAT(b.[' + c.name + '] ,''yyyyMMddHHmmss'') FROM [' + #table_name + '] a WITH(NOLOCK) , [' + #table_name + '] b WITH(NOLOCK) ' + #where_clause + ' AND FORMAT(ISNULL(a.[' + c.name + '],' + '''' + '1900-01-01' + '''' + ') ,''yyyyMMddHHmmss'') != FORMAT(ISNULL(b.[' + c.name + '],' + '''' + '1900-01-01' + '''' + ') ,''yyyyMMddHHmmss'')'
ELSE
' INSERT INTO #T SELECT ''[' + c.name + ']'', CAST(a.[' + c.name + '] AS NVARCHAR(MAX)), CAST(b.[' + c.name + '] AS NVARCHAR(MAX)) FROM [' + #table_name + '] a WITH(NOLOCK) , [' + #table_name + '] b WITH(NOLOCK) ' + #where_clause + ' AND CAST(ISNULL(a.[' + c.name + '],' + '''' + '''' + ') AS NVARCHAR(MAX)) != CAST(ISNULL(b.[' + c.name + '],' + '''' + '''' + ') AS NVARCHAR(MAX))'
END
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
WHERE t.name = #table_name
AND c.name NOT IN (
SELECT items
FROM dbo.Split(#excluded_columns, ',')
)
FOR XML path('')
)
SET #sqlstmt += #cols + ' SELECT * FROM #T';
--PRINT #sqlstmt;
EXEC sp_executesql #sqlstmt
END
To Execute
EXECUTE dbo.IdentifyNotMatchingColumnDataBetween2Rows 'TableName','Id,UpdateTimeStamp,InsertTimeStamp,Last Checked,IsDuplicate,NotMatchingColumns,',#row_id_1,#row_id_2;

Implementing a naming standard for keys, indexes, constraints

I have a database with a lot of tables, and I want to rename the primary/foreign keys, indexes and default constraints according to the following rules :
Primary keys : PK_<table name>
Foreign keys : FK_<table_name>_<column name1>_column name2>...
Indexes : IX_<table_name>_<column name1>_column name2>...
Default Constraints : DF_<table_name>_<column name>
Check Constraints : CK_<table_name>_<column name>
Someone has already done a similar SQL script ?
To rename Primary Keys to simply PK_TableName:
CREATE PROCEDURE dbo.Rename_PrimaryKeys
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10) + 'EXEC sp_rename '''
+ REPLACE(name, '''', '''''') + ''', ''PK_'
+ REPLACE(OBJECT_NAME(parent_object_id), '''', '') + ''', ''OBJECT'';'
FROM sys.key_constraints
WHERE type = 'PK'
AND name <> 'PK_' + REPLACE(OBJECT_NAME(parent_object_id), '''', '')
AND OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
To rename FKs with the scheme FK_TableName_col_col_ReferencedName_col_col:
CREATE PROCEDURE dbo.Rename_ForeignKeys_WithColumns
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10)
+ 'EXEC sp_rename ''' + REPLACE(name, '''', '''''')
+ ''', ''FK_' + REPLACE(OBJECT_NAME(fk.parent_object_id), '''', '')
+ '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '')
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
+ '_' + REPLACE(OBJECT_NAME(fk.referenced_object_id), '''', '')
+ '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '')
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.referenced_column_id = c.column_id
AND fkc.referenced_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
+ ''', ''OBJECT'';'
FROM sys.foreign_keys AS fk
WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
For foreign keys if you just want FK_TableName_ReferencedName then it's a lot simpler:
CREATE PROCEDURE dbo.Rename_ForeignKeys
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10) + 'EXEC sp_rename '''
+ REPLACE(name, '''', '''''') + ''', ''FK_'
+ REPLACE(OBJECT_NAME(parent_object_id), '''', '')
+ '_' + REPLACE(OBJECT_NAME(referenced_object_id), '''', '')
+ ''', ''OBJECT'';'
FROM sys.foreign_keys
WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
For indexes, this will rename any indexes IX_TableName_Col1_Col2.... It will ignore primary keys (since they are dealt with separately above), will add UQ_ to unique indexes/constraints (so IX_UQ_TableName_Col1_Col2..., will treat unique constraints and unique indexes the same, and will ignore included columns. (Note that ignoring included columns could produce a naming conflict if you have redundant indexes that only differ by included columns.)
CREATE PROCEDURE dbo.Rename_Indexes
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10)
+ 'EXEC sp_rename ''' + REPLACE(i.name, '''', '''''')
+ ''', ''IX_' + CASE is_unique_constraint WHEN 1 THEN 'UQ_' ELSE '' END
+ REPLACE(OBJECT_NAME(i.[object_id]), '''', '')
+ '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '')
FROM sys.columns AS c
INNER JOIN sys.index_columns AS ic
ON ic.column_id = c.column_id
AND ic.[object_id] = c.[object_id]
WHERE ic.[object_id] = i.[object_id]
AND ic.index_id = i.index_id
AND is_included_column = 0
ORDER BY ic.index_column_id
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'')
+''', ''OBJECT'';'
FROM sys.indexes AS i
WHERE index_id > 0
AND is_primary_key = 0 -- dealt with separately
AND OBJECTPROPERTY(i.[object_id], 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
For default constraints:
CREATE PROCEDURE dbo.Rename_DefaultConstraints
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10)
+ 'EXEC sp_rename ''' + REPLACE(dc.name, '''', '''''')
+ ''', ''DF_' + REPLACE(OBJECT_NAME(dc.parent_object_id), '''','')
+ '_' + REPLACE(c.name, '''', '') + ''', ''OBJECT'';'
FROM sys.default_constraints AS dc
INNER JOIN sys.columns AS c
ON dc.parent_object_id = c.[object_id]
AND dc.parent_column_id = c.column_id
AND OBJECTPROPERTY(dc.parent_object_id, 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
And finally check constraints:
CREATE PROCEDURE dbo.Rename_CheckConstraints
#PrintOnly BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + CHAR(13) + CHAR(10)
+ 'EXEC sp_rename ''' + REPLACE(cc.name, '''', '''''')
+ ''', ''CK_' + REPLACE(OBJECT_NAME(cc.parent_object_id), '''','')
+ '_' + REPLACE(c.name, '''', '') + ''', ''OBJECT'';'
FROM sys.check_constraints AS cc
INNER JOIN sys.columns AS c
ON cc.parent_object_id = c.[object_id]
AND cc.parent_column_id = c.column_id
AND OBJECTPROPERTY(dc.parent_object_id, 'IsMsShipped') = 0;
PRINT #sql;
IF #PrintOnly = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END
END
GO
Note that PRINT won't necessarily reveal the entire statement, depending on your settings for results in text and the size of the statement. But it should be good enough to eyeball that the scripts are doing the right job. I set them all to PrintOnly by default.
And to rename the foreign keys, you can use something like this (this is not yet doing exactly what you wanted - but close enough to get started on it):
DECLARE RenameFKCursor CURSOR FAST_FORWARD
FOR
SELECT
'dbo.sp_rename #objName = ''' + fk.Name + ''', #NewName = ''FK_' + t.Name + '_' + ref.Name + ''', #objtype = ''OBJECT'''
FROM
sys.foreign_keys fk
INNER JOIN
sys.tables t ON fk.parent_object_id = t.object_id
INNER JOIN
sys.tables ref ON fk.referenced_object_id = ref.object_id
WHERE
fk.is_system_named = 1
DECLARE #RenameFKStmt NVARCHAR(500)
OPEN RenameFKCursor
FETCH NEXT FROM RenameFKCursor INTO #RenameFKStmt
WHILE (##fetch_status <> -1)
BEGIN
IF (##fetch_status <> -2)
BEGIN
PRINT #RenameFKStmt
EXEC(#RenameFKStmt)
END
FETCH NEXT FROM RenameFKCursor INTO #RenameFKStmt
END
CLOSE RenameFKCursor
DEALLOCATE RenameFKCursor
GO
Basically, you iterate over all foreign keys defined in your database, and you rename them to some name that you decide on how to construct in the SELECT that is the basis of this cursor.
Then you run the cursor over all results, and execute the dbo.sp_rename stored procedure to rename your FK constraint to whatever you want them to be.
Using Aaron's approach of just basically building up one single huge SQL statement, you could even get away without having to use a cursor.
This would be the very similar code to rename the "system-named" default constraints to your own naming convention - it uses the same approach as above, a SELECT against the system catalog views, and then a cursor to iterate over all entries and build up and execute a SQL rename statement:
DECLARE DFCursor CURSOR FAST_FORWARD
FOR
SELECT
dc.Name,
t.Name,
c.Name
FROM
sys.default_constraints dc
INNER JOIN
sys.tables t ON dc.parent_object_id = t.object_id
INNER JOIN
sys.columns c ON dc.parent_column_id = c.column_id AND dc.parent_object_id = c.object_id
WHERE
is_system_named = 1
DECLARE #OldConstraintName sysname, #TableName sysname, #ColumnName sysname
OPEN DFCursor
FETCH NEXT FROM DFCursor INTO #OldConstraintName, #TableName, #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #Stmt NVARCHAR(999)
SET #Stmt = 'dbo.sp_rename #objName = ''' + #OldConstraintName + ''', #NewName = ''DF_' + #TableName + '_' + #ColumnName + ''', #objtype = ''OBJECT'''
PRINT #Stmt
EXEC (#Stmt)
FETCH NEXT FROM DFCursor INTO #OldConstraintName, #TableName, #ColumnName
END
CLOSE DFCursor
DEALLOCATE DFCursor
Provided solutions will break if DB has similar tables in different schemas. Here's my modification of this solution, that i use.
CREATE PROCEDURE dbo._ImplementNamingStandard
#SELECT_Only BIT = 1,
#PrimaryKeys BIT = 1,
#ForeignKeys BIT = 1,
#Indexes BIT = 1,
#UniqueConstraints BIT = 1,
#DefaultConstraints BIT = 1,
#CheckConstraints BIT = 1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX), #cr CHAR(2);
SELECT #sql = N'', #cr = CHAR(13) + CHAR(10);
DECLARE #TableLimit TINYINT, #ColumnLimit TINYINT;
SELECT #TableLimit = 24, #ColumnLimit = 24;
Primary Keys:
IF #PrimaryKeys = 1
BEGIN
SELECT #sql = #sql + #cr + #cr + N'/* ---- Primary Keys ---- */' + #cr;
SELECT #sql = #sql + #cr + N'EXEC sp_rename #objname = N'''
+ SCHEMA_NAME(schema_id) + '.'
+ REPLACE(name, '''', '''''') + ''', #newname = N''PK_'
+ LEFT(REPLACE(OBJECT_NAME(parent_object_id), '''', ''), #TableLimit) + ''';'
FROM sys.key_constraints
WHERE type = 'PK'
AND is_ms_shipped = 0;
END
Foreign Keys:
IF #ForeignKeys = 1
BEGIN
SELECT #sql = #sql + #cr + #cr + N'/* ---- Foreign Keys ---- */' + #cr;
SELECT #sql = #sql + #cr + N'EXEC sp_rename #objname = N'''
+ SCHEMA_NAME(f.schema_id) + '.'
+ REPLACE(f.name, '''', '''''') + ''', #newname = N''FK_'
+ LEFT(REPLACE(t.name, '''', ''), #TableLimit)
+ '_' + LEFT(REPLACE(t2.name, '''', ''), #TableLimit)
+ '_' + LEFT(REPLACE(c.name, '''', ''), #ColumnLimit)
+ ''';'
FROM
sys.foreign_keys as f
inner join sys.foreign_key_columns as fk on f.object_id = fk.constraint_object_id
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.tables as t2 on fk.referenced_object_id = t2.object_id
inner join sys.columns as c on fk.parent_object_id = c.object_id and
fk.parent_column_id = c.column_id
WHERE f.is_ms_shipped = 0;
END
Unique constraints:
IF (#UniqueConstraints = 1 OR #Indexes = 1)
BEGIN
SELECT #sql = #sql + #cr + #cr + N'/* ---- Indexes / Unique Constraints ---- */' + #cr;
SELECT #sql = #sql + #cr + N'EXEC sp_rename #objname = N'''
+ CASE is_unique_constraint WHEN 0 THEN
QUOTENAME(REPLACE(OBJECT_NAME(i.[object_id]), '''', '''''')) + '.' ELSE '' END
+ QUOTENAME(REPLACE(i.name, '''', '''''')) + ''', #newname = N'''
+ CASE is_unique_constraint WHEN 1 THEN 'UQ_' ELSE 'IX_'
+ CASE is_unique WHEN 1 THEN 'U_' ELSE '' END
END + CASE has_filter WHEN 1 THEN 'F_' ELSE '' END
+ LEFT(REPLACE(OBJECT_NAME(i.[object_id]), '''', ''), #TableLimit)
+ '_' + STUFF((SELECT '_' + LEFT(REPLACE(c.name, '''', ''), #ColumnLimit)
FROM sys.columns AS c
INNER JOIN sys.index_columns AS ic
ON ic.column_id = c.column_id
AND ic.[object_id] = c.[object_id]
WHERE ic.[object_id] = i.[object_id]
AND ic.index_id = i.index_id
AND is_included_column = 0
ORDER BY ic.index_column_id FOR XML PATH(''),
TYPE).value('.', 'nvarchar(max)'), 1, 1, '') +''';'
FROM sys.indexes AS i
WHERE index_id > 0 AND is_primary_key = 0 AND type IN (1,2)
AND OBJECTPROPERTY(i.[object_id], 'IsMsShipped') = 0;
END
Default constraints:
IF #DefaultConstraints = 1
BEGIN
SELECT #sql = #sql + #cr + #cr + N'/* ---- DefaultConstraints ---- */' + #cr;
SELECT #sql = #sql + #cr + N'EXEC sp_rename #objname = N'''
+ SCHEMA_NAME(schema_id) + '.'
+ REPLACE(dc.name, '''', '''''') + ''', #newname = N''DF_'
+ LEFT(REPLACE(OBJECT_NAME(dc.parent_object_id), '''',''), #TableLimit)
+ '_' + LEFT(REPLACE(c.name, '''', ''), #ColumnLimit) + ''';'
FROM sys.default_constraints AS dc
INNER JOIN sys.columns AS c
ON dc.parent_object_id = c.[object_id]
AND dc.parent_column_id = c.column_id
AND dc.is_ms_shipped = 0;
END
Check Constraints:
IF #CheckConstraints = 1
BEGIN
SELECT #sql = #sql + #cr + #cr + N'/* ---- CheckConstraints ---- */' + #cr;
SELECT #sql = #sql + #cr + N'EXEC sp_rename #objname = N'''
+ SCHEMA_NAME(schema_id) + '.'
+ REPLACE(cc.name, '''', '''''') + ''', #newname = N''CK_'
+ LEFT(REPLACE(OBJECT_NAME(cc.parent_object_id), '''',''), #TableLimit)
+ '_' + LEFT(REPLACE(c.name, '''', ''), #ColumnLimit) + ''';'
FROM sys.check_constraints AS cc
INNER JOIN sys.columns AS c
ON cc.parent_object_id = c.[object_id]
AND cc.parent_column_id = c.column_id
AND cc.is_ms_shipped = 0;
END
SELECT #sql;
IF #SELECT_Only = 0 AND #sql > N''
BEGIN
EXEC sp_executesql #sql;
END

Resources