Home Forums SQL Server 2008 T-SQL (SS2K8) Making scripts rerunnable RE: Making scripts rerunnable
May 23, 2018 at 4:05 pm
Matt Miller (4) - Wednesday, May 23, 2018 3:39 PMmtnbikur - Wednesday, May 23, 2018 2:05 PMI've always tried to make any script I write rerunnable whether it's modifying a stored proc, altering a table structure or whatever. And I've always been successful, even when it comes to modifying a primary key or something. Here's one I haven't run into before though.Setup:
IF OBJECT_ID('dbo.EmpExample') IS NOT NULL DROP TABLE dbo.EmpExample
IF OBJECT_ID('dbo.BldgExample') IS NOT NULL DROP TABLE dbo.BldgExampleCREATE TABLE dbo.EmpExample
(
EmpId INT,
EmpName VARCHAR(25)
)CREATE TABLE dbo.BldgExample
(
EmpId INT,
BldgId INT,
BadgeNum INT
)INSERT dbo.EmpExample
(
EmpId,
EmpName
)
SELECT 1, 'Kevin'
UNION SELECT 2, 'John'
UNION SELECT 3, 'Michael'INSERT dbo.BldgExample
(
EmpId,
BldgId,
BadgeNum
)
SELECT 1, 47, 123
UNION SELECT 2, 47, 124
UNION SELECT 3, 47, 125
UNION SELECT 2, 55, 124So John works in two buildings, so I want to clean up how this data is stored. Makes more sense to tie the BadgeNum to the actual employee and not the building he's entering.
IF NOT EXISTS (
SELECT TOP 1 1
FROM sys.tables t
INNER JOIN sys.columns c
ON t.object_id = c.object_id
WHERE t.name = 'EmpExample'
AND c.name = 'BadgeNum')
BEGINALTER TABLE dbo.EmpExample
ADD BadgeNum INTEND;
GOIF EXISTS (
SELECT TOP 1 1
FROM sys.tables t
INNER JOIN sys.columns c
ON t.object_id = c.object_id
WHERE t.name = 'BldgExample'
AND c.name = 'BadgeNum')
BEGIN
UPDATE emp
SET BadgeNum = bldg.BadgeNum
FROM dbo.EmpExample emp
INNER JOIN dbo.BldgExample bldg
ON emp.EmpId = bldg.EmpIdALTER TABLE dbo.BldgExample
DROP COLUMN BadgeNum
END;
GOWhen I run this the first time, it works just great. But if this is part of a large change set where things get tweaked and the whole thing gets rerun, I'd like the whole thing to be rerunnable. It fails the 2nd time around with a "column doesn't exist" error. I know it doesn't exist. That's why I wrapped it in an "if exists".
I know there are quicker ways to write the "if exists" portions. And overlook the fact that the update will have two source rows for John from the BldgExample table. I was trying to come up with a contrived scenario.
Ideas? Comments? Rude remarks?
Thanks!
Keith
Don't have time to test this, but if the DML statement using the column you've dropped were being called in dynamic SQL, then your IF EXISTS would actually work and the syntax checker wouldn't complain. So this would give you idempotency I think.
That worked great! Thanks Matt!