Skip to content

Instantly share code, notes, and snippets.

@lionofdezert
Created November 29, 2013 18:48
Show Gist options
  • Save lionofdezert/7710251 to your computer and use it in GitHub Desktop.
Save lionofdezert/7710251 to your computer and use it in GitHub Desktop.
Stored Procedure, to create missing primary keys at target database by comparing both source and target databases.
--DROP IF ALREADY CREATED
IF EXISTS ( SELECT 1
FROM SYS.procedures
WHERE NAME = 'SYNC_CreatePrimaryKeys' )
DROP PROC SYNC_CreatePrimaryKeys
GO
--CREATE PROCEDURE
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
Stored Procedure, to create missing primary keys at target database by comparing both source and target databases.
EXEC [dbo].[SYNC_CreatePrimaryKeys] 'AdventureWork_StableVersion','AventureWork_Target'
*/
CREATE PROCEDURE [dbo].[SYNC_CreatePrimaryKeys]
(
@SyncFromDB VARCHAR(200), --Source database name
@SyncToDB VARCHAR(200) --Target database name
)
AS
BEGIN
CREATE TABLE #AlterStatements ( TSQLStmt VARCHAR(MAX) )
EXEC('
INSERT INTO #AlterStatements (TSQLStmt)
SELECT '' IF NOT EXISTS(SELECT 1 FROM '+@SyncToDB+'.SYS.OBJECTS WHERE NAME = ''''''+Constraint_name+'''''') ALTER TABLE ['+@SyncToDB+'].[''+table_schema+''].[''+Table_name+''] ADD CONSTRAINT ''+Constraint_name+'' PRIMARY KEY CLUSTERED
(''+
REVERSE(CASE WHEN LEFT(LTRIM(REVERSE(KEYCOLS)),1)='',''THEN SUBSTRING(REVERSE(KEYCOLS),CHARINDEX('','',REVERSE(KEYCOLS),1)+1,LEN(REVERSE(KEYCOLS))) ELSE REVERSE(KEYCOLS) END)
+
'')
ELSE
ALTER TABLE ['+@SyncToDB+'].[''+table_schema+''].[''+Table_name+''] ADD CONSTRAINT ''+Constraint_name+''_1 PRIMARY KEY CLUSTERED
(''+
REVERSE(CASE WHEN LEFT(LTRIM(REVERSE(KEYCOLS)),1)='',''THEN SUBSTRING(REVERSE(KEYCOLS),CHARINDEX('','',REVERSE(KEYCOLS),1)+1,LEN(REVERSE(KEYCOLS))) ELSE REVERSE(KEYCOLS) END)
+
'') ''
FROM(
SELECT TC.TABLE_SCHEMA,TC.TABLE_NAME,TC.CONSTRAINT_NAME ,SUBSTRING(list,1,LEN(list)-1) AS kEYCOLS
FROM '+@SyncFromDB+'..sysobjects so
INNER JOIN '+@SyncFromDB+'.information_schema.table_constraints tc ON tc.Table_name = so.Name AND tc.Constraint_Type = ''PRIMARY KEY''
CROSS APPLY
(
SELECT ''[''+ Column_Name + ''], ''''''
FROM '+@SyncFromDB+'.information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY
ORDINAL_POSITION
FOR XML PATH('''')
) j (list)
)MASTERDB
WHERE NOT EXISTS
(
SELECT * FROM
(
SELECT TC.TABLE_SCHEMA,TC.TABLE_NAME,TC.CONSTRAINT_NAME ,SUBSTRING(list,1,LEN(list)-1) AS kEYCOLS
FROM '+@SyncToDB+'..sysobjects so
INNER JOIN '+@SyncToDB+'.information_schema.table_constraints tc ON tc.Table_name = so.Name AND tc.Constraint_Type = ''PRIMARY KEY''
CROSS APPLY
(
SELECT ''['' + Column_Name + ''], ''''''
FROM '+@SyncToDB+'.information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY ORDINAL_POSITION
FOR XML PATH('''')
) j (list)
)SLAVERDB
WHERE SLAVERDB.TABLE_NAME=MASTERDB.TABLE_NAME
AND SLAVERDB.TABLE_SCHEMA=MASTERDB.TABLE_SCHEMA
AND SLAVERDB.kEYCOLS=MASTERDB.kEYCOLS
)
')
----CURSOR TO EXECUTE/PRINT EACH STATEMENT SEPARATELY-----
DECLARE MY_CURSOR CURSOR READ_ONLY
FOR SELECT TSQLStmt
FROM #AlterStatements
OPEN My_Cursor
DECLARE @ObjectName VARCHAR(MAX),
@SQLstmt VARCHAR(MAX)
Fetch NEXT FROM MY_Cursor INTO @ObjectName
While ( @@FETCH_STATUS <> -1 )
BEGIN
SELECT @SQLstmt = REPLACE(@ObjectName, '''[', ' [')
EXEC ( @SQLstmt
)
-- PRINT (@SQLstmt)
FETCH NEXT FROM MY_CURSOR INTO @ObjectName
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
-----
DROP TABLE #AlterStatements
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment