Search This Blog

Tuesday, February 12, 2008

damned system named constraints

problem: you need to write a script to alter or drop a column as part of a hotfix for your clients. this column was created with a default constraint, but this default constraint was not explicitly named, thus a system-generated name was given (which looks something like 'DF__(partialtablename)__(partialcolumnname)__(random numbers and letters)' in SQL Server 2005). since the name of the constraint will be different on every client, you can't write a straight forward 'ALTER TABLE DROP CONSTRAINT ' statement.

solution: system tables aaaaaaaand ...

dynamic sql!!! weeeeeeeeeeeeeeeee

(i don't know why i got excited about something i genearlly preach against, but, as i've said before, dynamic sql is a necessary evil and can be very useful)

/*1. i think it is good practice to validate that something exists before dropping it (or does not exist before adding it). that way if a sql query that is part of a hotfix is accidentally run more than once, no errors should occur. this script simply checks to see if there is a constraint on a column named 'col_a' in table_a:*/

IF EXISTS (SELECT OBJECT_NAME(constid) FROM sysconstraints CN
INNER JOIN syscolumns CO
ON CN.id = OBJECT_ID('table_a') AND CO.id = CN.id AND
CO.name = 'col_a' AND CN.colid = CO.colorder)
BEGIN

/*2. the following sample then removes the constraint from the column:*/

DECLARE @Sql AS NVARCHAR(2000)

SELECT @Sql = 'ALTER TABLE table_a DROP CONSTRAINT ' + OBJECT_NAME(constid)
FROM sysconstraints CN
INNER JOIN syscolumns CO
ON CN.id = OBJECT_ID('table_a') AND CO.id = CN.id AND
CO.name = 'col_a' AND CN.coldid = CO.colorder

EXEC(@Sql)

END

/* to be extra safe, you may want to include the type of constraint you are dropping as part of the join. the type of constraint is contained in the pseudo-bit-mask value of the sysconstraints 'status' column. as an example, a default constraint will have a status value of '133141' */

No comments: