Created
November 7, 2013 05:00
-
-
Save gekola/7349204 to your computer and use it in GitHub Desktop.
TSQL deep table copy procedure example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
USE [AdventureWorks2012]; | |
GO | |
ALTER PROCEDURE [dbo].[CopyTable] | |
@src_name nvarchar(4000) | |
, @dst_name nvarchar(4000) | |
AS | |
BEGIN | |
DECLARE @sql nvarchar(4000) | |
, @src_schema nvarchar(4000) = OBJECT_SCHEMA_NAME(OBJECT_ID(@src_name)) | |
, @src_table nvarchar(4000) = OBJECT_NAME(OBJECT_ID(@src_name)); | |
-- Copy data | |
SET @sql = 'SELECT * INTO ' + @dst_name + ' FROM ' + @src_name + ';'; | |
EXEC (@sql); | |
DECLARE @constrs TABLE ([name] nvarchar(4000), [col] nvarchar(4000), [type] nvarchar(4000)) | |
INSERT INTO @constrs | |
SELECT [c].[CONSTRAINT_NAME], [c].[COLUMN_NAME], [tk].[CONSTRAINT_TYPE] | |
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS [tk] | |
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE [c] | |
ON [tk].TABLE_NAME = @src_table | |
AND [tk].[TABLE_SCHEMA] = @src_schema | |
AND [c].[TABLE_NAME] = [tk].[TABLE_NAME] | |
AND [c].[TABLE_SCHEMA] = [tk].[TABLE_SCHEMA] | |
AND [c].[CONSTRAINT_NAME] = [tk].[CONSTRAINT_NAME] | |
WHERE [tk].[CONSTRAINT_TYPE] != N'FOREIGN KEY'; | |
-- Copy PK | |
DECLARE @pkCol NVARCHAR(4000) = STUFF(( | |
SELECT N',' + [col] | |
FROM @constrs | |
WHERE [type] = N'PRIMARY KEY' | |
FOR XML PATH(N'')), 1, 1, N''); | |
SET @sql = 'ALTER TABLE ' + @dst_name + ' ADD CONSTRAINT ' | |
+ (SELECT TOP 1 name FROM @constrs WHERE [type] = N'PRIMARY KEY') | |
+ N' PRIMARY KEY (' + @pkCol + ');'; | |
EXEC (@sql); | |
/* It seems there are no more constraints in @constrs. | |
* This fact is to be investigated. | |
*/ | |
DECLARE @count int, @s int = 0; | |
DECLARE @name nvarchar(4000), @def nvarchar(4000), @col nvarchar(4000); | |
-- checks | |
DECLARE @constrs2 TABLE ([name] nvarchar(4000), [definition] nvarchar(4000)); | |
INSERT INTO @constrs2 | |
SELECT [name], [definition] | |
FROM [sys].[CHECK_CONSTRAINTS] [tk] | |
WHERE [tk].[parent_object_id] = OBJECT_ID(@src_name); | |
SELECT @count=COUNT(*) FROM @constrs2; | |
WHILE (@s < @count) | |
BEGIN | |
SELECT @name=[name], @def=[definition] | |
FROM @constrs2 ORDER BY [name] OFFSET @s ROWS FETCH NEXT 1 ROW ONLY; | |
EXEC(N'ALTER TABLE ' + @dst_name + N' ADD CONSTRAINT [' + @name + N'] CHECK ' + @def + N';'); | |
SET @s = @s + 1; | |
END | |
-- Default value constraints | |
DECLARE @constrs3 TABLE ([name] nvarchar(4000) | |
, [definition] nvarchar(4000) | |
, [column] nvarchar(4000)); | |
SET @s = 0; | |
INSERT INTO @constrs3 | |
SELECT [tk].[name], [definition], [c].[name] | |
FROM [sys].[DEFAULT_CONSTRAINTS] [tk] | |
JOIN [sys].[columns] AS [c] | |
ON [tk].[parent_object_id] = [c].[object_id] AND [tk].[parent_column_id] = [c].[column_id] | |
WHERE [tk].[parent_object_id] = OBJECT_ID(@src_name); | |
SELECT @count=COUNT(*) FROM @constrs3; | |
WHILE (@s < @count) | |
BEGIN | |
SELECT @name=[name], @def=[definition], @col=[column] | |
FROM @constrs3 ORDER BY [name] OFFSET @s ROWS FETCH NEXT 1 ROW ONLY; | |
EXEC(N'ALTER TABLE ' + @dst_name + N' ADD CONSTRAINT [' + @name | |
+ N'] DEFAULT ' + @def + N' FOR [' + @col + N'];'); | |
SET @s = @s + 1; | |
END | |
-- Default indexes | |
DECLARE @indexes TABLE ([id] int); | |
SET @s = 0; | |
INSERT INTO @indexes | |
SELECT [index_id] | |
FROM [sys].[indexes] [tk] | |
WHERE [tk].[object_id] = OBJECT_ID(@src_name) | |
AND [tk].[is_primary_key] = 0 | |
AND [tk].[is_unique_constraint] = 0; | |
SELECT @count=COUNT(*) FROM @indexes; | |
WHILE (@s < @count) | |
BEGIN | |
DECLARE @index_id int | |
, @unique nvarchar(7) -- UNIQUE | |
, @clustered nvarchar(13) -- NONCLUSTERED | |
, @is_padded nvarchar(4) -- PAD_INDEX = OFF | |
-- STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF | |
, @ignore_dup_key nvarchar(4) -- IGNORE_DUP_KEY = OFF | |
-- DROP_EXISTING = OFF, ONLINE = OFF | |
, @allow_row_locks nvarchar(4) -- ALLOW_ROW_LOCKS = ON | |
, @allow_page_locks nvarchar(4) -- ALLOW_PAGE_LOCKS = ON | |
; | |
SELECT @name=[name], @index_id=[index_id] | |
, @unique = CASE WHEN ([is_unique] = 1) THEN N'UNIQUE' ELSE N'' END | |
, @clustered = [type_desc] | |
, @is_padded = CASE WHEN ([is_padded] = 1) THEN N'ON' ELSE N'OFF' END | |
, @ignore_dup_key = CASE WHEN ([ignore_dup_key] = 1) THEN N'ON' ELSE N'OFF' END | |
, @allow_row_locks = CASE WHEN ([allow_row_locks] = 1) THEN N'ON' ELSE N'OFF' END | |
, @allow_page_locks = CASE WHEN ([allow_page_locks] = 1) THEN N'ON' ELSE N'OFF' END | |
FROM [sys].[indexes] INNER JOIN @indexes [i] ON [i].[id] = [index_id] | |
WHERE [sys].[indexes].[object_id] = OBJECT_ID(@src_name) | |
ORDER BY [i].[id] OFFSET @s ROWS FETCH NEXT 1 ROW ONLY; | |
SET @col = STUFF(( | |
SELECT N',[' + [c].[name] + N'] ' | |
+ CASE WHEN ([ctk].[is_descending_key] != 0) THEN N'DESC' ELSE N'ASC' END | |
FROM [sys].[index_columns] [ctk] | |
INNER JOIN [sys].[columns] [c] | |
ON [c].[object_id] = [ctk].[object_id] AND [c].[column_id] = [ctk].[column_id] | |
WHERE [ctk].[object_id] = OBJECT_ID(@src_name) | |
AND [ctk].[index_id] = @index_id | |
FOR XML PATH(N'') | |
), 1, 1, N''); | |
EXEC(N'CREATE ' + @unique + N' ' + @clustered + N' INDEX ' + @name | |
+ N' ON ' + @dst_name + N' (' + @col + N') WITH (PAD_INDEX = ' + @is_padded | |
+ N', STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = ' + @ignore_dup_key | |
+ N', DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ' + @allow_row_locks | |
+ N', ALLOW_PAGE_LOCKS = ' + @allow_page_locks + N') ON [PRIMARY]'); | |
SET @s += 1; | |
END | |
END | |
GO | |
IF (OBJECT_ID(N'dbo.dest1') IS NOT NULL) DROP TABLE [dbo].[dest1]; | |
GO | |
EXEC [dbo].[CopyTable] @src_name=N'[HumanResources].[Employee]', @dst_name=N'[dbo].[dest1]'; | |
GO |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Triggers copy does not seem reasonable due to target table is often referred by name from there.