J'écris un script SQL pour supprimer la colonne et une contrainte par défaut. Le script suivant fonctionne bien, mais je voudrais savoir si c’est une bonne façon de le faire.
Puis-je supprimer une contrainte par défaut avec une colonne dans une instruction au lieu d’en utiliser deux distinctes?
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF_Employees_EmpID]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [DF_Employees_EmpID]
END
GO
BEGIN
ALTER TABLE [dbo].[Employees] DROP COLUMN [EmpID]
END
A partir de SQL Server 2005, vous pouvez supprimer la contrainte et la colonne dans une seule instruction.
La syntaxe est
ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name
DROP { [ CONSTRAINT ] constraint_name | COLUMN column } [ ,...n ]
L'accent est mis sur [ ... n] , indiquant plusieurs termes.
NB! Étant donné que les termes sont traités de manière séquentielle, si la colonne supprimée fait partie de la contrainte, la contrainte doit être le premier terme, suivi du terme de colonne.
Dans votre exemple:
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [DF_Employees_EmpID], COLUMN [EmpID]
Donc, votre code serait:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF_Employees_EmpID]') AND type = 'D')
BEGIN
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [DF_Employees_EmpID], COLUMN [EmpID]
END
GO
Dans SQL Server 2016, ils ont introduit la clause IF EXISTS, qui supprime la nécessité de vérifier l'existence de la contrainte en premier, par exemple.
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT IF EXISTS [DF_Employees_EmpID], COLUMN IF EXISTS [EmpID]
Voici un autre moyen de supprimer une colonne et les contraintes par défaut en vérifiant leur existence avant de les supprimer:
-------------------------------------------------------------------------
-- Drop COLUMN
-- Name of Column: Column_EmployeeName
-- Name of Table: table_Emplyee
--------------------------------------------------------------------------
IF EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'table_Emplyee'
AND COLUMN_NAME = 'Column_EmployeeName'
)
BEGIN
IF EXISTS ( SELECT 1
FROM sys.default_constraints
WHERE object_id = OBJECT_ID('[dbo].[DF_table_Emplyee_Column_EmployeeName]')
AND parent_object_id = OBJECT_ID('[dbo].[table_Emplyee]')
)
BEGIN
------ DROP Contraint
ALTER TABLE [dbo].[table_Emplyee] DROP CONSTRAINT [DF_table_Emplyee_Column_EmployeeName]
PRINT '[DF_table_Emplyee_Column_EmployeeName] was dropped'
END
-- ----- DROP Column -----------------------------------------------------------------
ALTER TABLE [dbo].table_Emplyee
DROP COLUMN Column_EmployeeName
PRINT 'Column Column_EmployeeName in images table was dropped'
END
--------------------------------------------------------------------------
-- ADD COLUMN Column_EmployeeName IN table_Emplyee table
--------------------------------------------------------------------------
IF NOT EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'table_Emplyee'
AND COLUMN_NAME = 'Column_EmployeeName'
)
BEGIN
----- ADD Column & Contraint
ALTER TABLE dbo.table_Emplyee
ADD Column_EmployeeName BIT NOT NULL
CONSTRAINT [DF_table_Emplyee_Column_EmployeeName] DEFAULT (0)
PRINT 'Column [DF_table_Emplyee_Column_EmployeeName] in table_Emplyee table was Added'
PRINT 'Contraint [DF_table_Emplyee_Column_EmployeeName] was Added'
END
GO
Comment vous l'avez c'est bien.
Une alternative serait
IF OBJECT_ID('DF_Employees_EmpID', 'D') IS NULL
BEGIN
ALTER TABLE dbo.Employees
DROP COLUMN EmpID
END
ELSE
BEGIN
ALTER TABLE dbo.Employees
DROP CONSTRAINT DF_Employees_EmpID,
COLUMN EmpID
END
Si la contrainte existe, elle combine les deux opérations en une seule instruction/transaction.
Une autre solution:
DECLARE @TableName sysname,
@Schema sysname,
@colname sysname,
@sql VARCHAR(1000)
SELECT @Schema = 'dbo',
@TableName = 'mytable',
@colname = 'mycol'
IF COL_LENGTH(@Schema+'.'+@TableName, @colname) IS NULL
BEGIN
PRINT 'Column does not exist!'
END
ELSE
BEGIN
SET @sql = ''
SELECT @sql += N' ALTER TABLE ' + @TableName + ' DROP CONSTRAINT ' + default_constraints.name + ';'
FROM sys.all_columns
INNER JOIN sys.tables
ON all_columns.object_id = TABLES.object_id
INNER JOIN sys.schemas
ON TABLES.schema_id = schemas.schema_id
INNER JOIN sys.default_constraints
ON all_columns.default_object_id = default_constraints.object_id
WHERE schemas.name = @Schema
AND tables.name = @TableName
AND all_columns.name = @colname
SET @sql += N' ALTER TABLE ' + @TableName + ' DROP COLUMN ' + @colname + ';'
PRINT ISNULL(@sql, 'NULL')
EXECUTE(@sql)
END