web-dev-qa-db-fra.com

Supprimer une colonne avec une contrainte par défaut dans SQL Server (IF EXISTS)

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
13
user1263981

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]
15
warren.sentient

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 
5
Catto

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.

0
Martin Smith

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
0
Sajjan Sarkar