BanisterMurray
5/12/2015 - 2:13 PM

SQL script templates for Safe re-runnable scripts

SQL script templates for Safe re-runnable scripts



--  This is the most important one!!!
USE MyAwesomeDB
GO
------------------------------------




-- ---------   SAFE CHECK IF TABLE EXISTS

IF (NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND  TABLE_Name = 'MyAwesome_TABLE_Name'))
BEGIN
	CREATE TABLE [dbo].[MyAwesome_TABLE_Name](

.......


	-- ---------   SAFE CHECK IF A "CHECK" CONSTRAINT EXISTS

	IF (EXISTS (SELECT 1 FROM sys.objects WHERE type_desc LIKE '%CONSTRAINT' and OBJECT_NAME(OBJECT_ID) = 'DF_MyAwesome_Check_Constraint'))
	BEGIN
		--------  NOTICE !!!!! -------
		--------  THIS REQUIRES THAT THIS CONSTRAINT IS ADDED BACK IN LATER IN THIS SCRIPT BELOW
		ALTER TABLE dbo.MyAwesome_TABLE_Name DROP CONSTRAINT DF_MyAwesome_Check_Constraint
	END



	-- ---------   SAFE CHECK IF FIELD EXISTS

	if NOT EXISTS(select 1 from sys.columns where Name = N'MyAwesome_FIELD_Name' and Object_ID = Object_ID(N'MyAwesome_TABLE_Name'))
	BEGIN            
		ALTER TABLE
			..........


	-- ---------   SAFE CHECK IF DEFAULT CONSTRAINT EXISTS

	IF (NOT EXISTS (SELECT 1 FROM sys.default_constraints WHERE object_id = OBJECT_ID(N'DF_MyAwesomeDEFAULT_CONSTRAINT_NAME')))
	BEGIN 
		ALTER TABLE
			..........


	-- ---------   SAFE CHECK IF REFERENTIAL CONSTRAINT EXISTS

	IF (NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME ='FK_MyAwesomeFOREIGN_KEY_CONSTRAINT'))   
	BEGIN 
		ALTER TABLE ...........



	-- ---------   SAFE CHECK IF INDEX (OR PRIMARY KEY) EXISTS

	IF (NOT EXISTS(SELECT 1 FROM sys.indexes WHERE Name = 'IX_MyAwesome_INDEX'))  -- also for PKs    PK_MyAwesome_PRIMARY_KEY
	BEGIN
		..........





-- ---------   SAFE CHECK IF SPECIFIC DATA ROW EXISTS

if (select COUNT(1) from [MyAwesome_TABLE_Name] where MyAwesome_FIELD_Name = 'MY_SPECIFIC_DATA') = 0
BEGIN
	INSERT INTO [dbo].[MyAwesome_TABLE_Name]

..........





-- ---------   SAFE CHECK IF STORED PROCEDURE EXISTS

IF NOT EXISTS (select 1 from Information_schema.Routines where Specific_schema='dbo' and specific_Name = 'spMyAwesome_PROC_Name' and Routine_Type='PROCEDURE')
BEGIN
	EXEC ('CREATE PROC dbo.spMyAwesome_PROC_Name AS SELECT 1')  
END
GRANT EXECUTE ON dbo.spMyAwesome_PROC_Name TO SPExecute
GO

ALTER PROCEDURE dbo.spMyAwesome_PROC_Name
(
	@ContestWinnerId int
)
AS
/*****************************************************************
Dev  		Date        Comments
---  		----------  --------------------------------------------------
Banister	9999-99-99  initial version
******************************************************************/
BEGIN

.........

GO






-- ---------   SAFE CHECK IF FUNCTION EXISTS

if NOT EXISTS (select 1 from Information_schema.Routines where Specific_schema='dbo' and specific_Name = 'fnMyAwesome_FUNCTION_Name' and Routine_Type='FUNCTION')
BEGIN
	EXEC ('CREATE FUNCTION [dbo].[fnMyAwesome_FUNCTION_Name] (@foo bit) RETURNS bit AS 	BEGIN 	RETURN 1;	END')
END
GO

ALTER FUNCTION [dbo].[fnMyAwesome_FUNCTION_Name] 
(
	@OrgID char(36)
)
RETURNS nvarchar(MAX)
AS
/*****************************************************************
Dev  	Date        Comments
---  	----------  --------------------------------------------------
YouName	99/99/9999  initial version
******************************************************************/
BEGIN

........







-- ---------   SAFE CHECK IF VIEW EXISTS

IF NOT EXISTS(select 1 FROM sys.views where name = 'vwMyAwesome_VIEW_Name')
	EXEC ('CREATE VIEW [dbo].[vwMyAwesome_VIEW_Name] AS SELECT 1 AS Forgot')  
GO

ALTER VIEW [dbo].[vwMyAwesome_VIEW_Name]
AS
/*****************************************************************
Dev  	Date        Comments
---  	----------  --------------------------------------------------
YouName	99/99/9999  initial version
******************************************************************/
SELECT 

.................







-- SERVER SPECIFIC


IF @@SERVERNAME = 'SFSQL\QA'              -- QA (or REPORTSERVER\SF for Reporting)
BEGIN
BEGIN
            UPDATE ContestInstance
            ...
END


IF @@SERVERNAME = 'SFSTAGE\SF'                  -- Staging (or RPTSERVERQA\SFR for Reporting)
BEGIN
BEGIN
            UPDATE ContestInstance
            ...
END


IF @@SERVERNAME = 'SFCLUSTER\SF'          -- Production (or RPTCLUSTER\SFR for Reporting)
BEGIN
            UPDATE ContestInstance
            ...
END

IF @@SERVERNAME NOT IN ( 'SFCLUSTER\SF' )
BEGIN
      PRINT 'Doing Nothing, we are not in Production OLTP'
      RETURN
END







--*************************************************  P R I M A R Y    K E Y S *****************************************************
-- Worst way to create a PK
CREATE TABLE [dbo].[MyAwesomeTable]
(
       JobID         int NOT NULL,
       ...
       [Comment]   nvarchar(2000) NULL,

PRIMARY KEY CLUSTERED                                                -- bad syntax ... this creates that nasty PK________________ name ...
(
       [JobID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY] ...


-- Better way to create a PK
CREATE TABLE [dbo].[MyAwesomeTable]
(
       JobID         int NOT NULL,
       ...
       [Comment]   nvarchar(2000) NULL,
CONSTRAINT [PK_MyAwesomeTable] PRIMARY KEY CLUSTERED 
(
       [JobID] ASC
)   WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY] ...


-- Best way to create a PK (because it is the most flexible)
ALTER TABLE dbo.MyAwesomeTable ADD CONSTRAINT
       PK_MyAwesomeTable PRIMARY KEY CLUSTERED 
       (
       JobID
       ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ...
       
--*************************************************  P R I M A R Y    K E Y S *****************************************************



-- Alternate Key (note the UNIQUE keyword and that it is non-clustered)
CREATE UNIQUE NONCLUSTERED INDEX [AK_Language] ON dbo.[Language]
(     [Code] ) 
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = ON, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]



-- Regular Index (note that it is non-clustered)
CREATE NONCLUSTERED INDEX [IX1_MyAwesomeTable_SiteID] ON dbo.MyAwesomeTable
(
       [SiteID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = ON, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO










-- -----------------------------------  FUNCTION  fnAdGroupCheckDateRangeOverlap
--
--  Crazy example of a Table with a CONSTRAINT USING FUNCTION


IF (EXISTS (SELECT 1 FROM sys.objects WHERE type_desc LIKE '%CONSTRAINT' and OBJECT_NAME(OBJECT_ID) = 'DF_AdGroup_Check_DateRangeOverlap'))
BEGIN
	--------  NOTICE !!!!! -------
	--------  THIS REQUIRES THAT THIS CONSTRAINT IS ADDED BACK IN LATER IN THIS SCRIPT BELOW
	ALTER TABLE dbo.AdGroup DROP CONSTRAINT DF_AdGroup_Check_DateRangeOverlap
END

IF NOT EXISTS (SELECT 1 FROM Information_schema.Routines WHERE Specific_schema='dbo' AND specific_Name = 'fnAdGroupCheckDateRangeOverlap' AND Routine_Type='FUNCTION')
BEGIN
	EXEC ('CREATE FUNCTION [dbo].[fnAdGroupCheckDateRangeOverlap] (@foo bit) RETURNS bit AS 	BEGIN 	RETURN 1;	END')
END
GO

ALTER FUNCTION [dbo].[fnAdGroupCheckDateRangeOverlap]
(
 @OrgID char(36),
 @AdAppTargetSizePositionID INT,
 @StartDate DATETIME,
 @EndDate DATETIME
) 
RETURNS INT
AS
--/*****************************************************************
--Used as a CHECK constraint in  TABLE  AdGroup


--Dev		 Date        Comments
-----		 ----------  ----------------------------------------------
--Banister 2012-08-01  Initial Version

--******************************************************************/
BEGIN

	DECLARE @ret INT;

	SELECT @ret = Count(1) 
	FROM dbo.AdGroup 
	WHERE  
		OrgID = @OrgID 
		AND AdAppTargetSizePositionID = @AdAppTargetSizePositionID
		AND 
		(	
			StartDate BETWEEN @StartDate AND @EndDate
			OR 
			EndDate BETWEEN @StartDate AND @EndDate
		)

	RETURN @ret

END
GO


	-- TABLE CONSTRAINT USING FUNCTION

	IF (NOT EXISTS (SELECT 1 FROM sys.default_constraints WHERE object_id = OBJECT_ID(N'DF_AdGroup_Check_DateRangeOverlap')))
	BEGIN 
		ALTER TABLE [dbo].[AdGroup]  WITH CHECK ADD  CONSTRAINT [DF_AdGroup_Check_DateRangeOverlap] 
			CHECK  (([dbo].[fnAdGroupCheckDateRangeOverlap]([OrgID],[AdAppTargetSizePositionID],[StartDate],[EndDate])=(0)))
	END
	GO







-------------------------------------------------
-- STOP INJECTIONS

SET   @SQL = REPLACE(@SQL,';','')               -- since we are going to be executing Dynamic SQL, make sure there is nothing funny in the Question Text
SET   @SQL = REPLACE(@SQL,'DROP TABLE ','')     -- since we are going to be executing Dynamic SQL, make sure there is nothing funny in the Question Text
SET   @SQL = REPLACE(@SQL,'ALTER TABLE ','')    -- Note that our own ALTER TABLE has a tab in it, not a space!!!
SET   @SQL = REPLACE(@SQL,'xp_cmdshell','')     -- since we are going to be executing Dynamic SQL, make sure there is nothing funny in the Question Text

EXEC SP_EXECUTESQL @SQL;