2013-12-17 5 views
6

Sto scrivendo uno script sql per il rilascio di una colonna e un vincolo predefinito. Il seguente script funziona bene, ma mi piace sapere se è un modo giusto per farlo.Rilasciare una colonna con un vincolo predefinito in SQL Server (IF EXISTS)

Posso eliminare un vincolo predefinito con una colonna in un'istruzione anziché utilizzare due separati?

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 
+0

ho pensato che dovevi fare separatamente - e fare, ** ** se avete bisogno di questo controllo condizionale. Se il vincolo esisterà sicuramente, allora può essere fatto come un singolo 'ALTER TABLE'. –

+0

il modo in cui ho fatto è giusto? – user1263981

+0

Sì, se è necessario il controllo condizionale, non esiste un modo reale per abbreviare questo codice. –

risposta

0

Come hai fatto.

Un'alternativa sarebbe

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 

Nel caso in cui il vincolo esiste questo combina le due operazioni in una singola istruzione/transazione.

5

Ecco un altro modo per eliminare una colonna & vincoli predefiniti con il controllo se esistono prima di farli cadere:

------------------------------------------------------------------------- 
-- 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 
8

In SQL Server 2005 verso l'alto si può cadere sia il vincolo e la colonna in una dichiarazione .

La sintassi è

ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name 
DROP { [ CONSTRAINT ] constraint_name | COLUMN column } [ ,...n ] 

L'enfasi è sulla [, ... n], indicando più termini.

NB! Poiché i termini vengono elaborati in modo sequenziale, se la colonna che viene rilasciata fa parte del vincolo che viene eliminato, il vincolo deve essere il primo termine, seguito dal termine della colonna.

Nel tuo esempio:

ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [DF_Employees_EmpID], COLUMN [EmpID] 

Così il vostro codice sarebbe:

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 

In SQL Server 2016 hanno introdotto l'IF EXISTS clausola che elimina la necessità di verificare l'esistenza del vincolo prima es

ALTER TABLE [dbo].[Employees] DROP CONSTRAINT IF EXISTS [DF_Employees_EmpID], COLUMN IF EXISTS [EmpID] 
0

Un'altra soluzione:

DECLARE @TableName sysname, 
     @Schema sysname, 
     @colname sysname, 
     @sql VARCHAR(1000) 

SELECT @Schema = 'dbo', 
     @TableName = 'mytable', 
     @colname = 'mycol' 


IF COL_LENGTH(@Schema+'.'[email protected], @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