Abilita o Disabilita i FOREIGNKEYS CONSTRAINT

Non avete mai avuto la necessità di disabilitare momentaneamente i vincoli FOREIGNKEYS su una o più tabelle ?

Ho avuto questa necessità durante la conversione di tipi dato per le colonne di alcune tabelle di un DB. Non conoscevo a priori il numero e il nome dei constraint e non vi era una regola universale utilizzata per la nomenclatura di questi vincoli.

Dopo un po' di tempo investito a studiare le tabelle di sistema... è arrivata una stored procedure CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE() che permette di abilitare/disabilitare i vincoli FOREIGNKEYS e l'assegnazione di valori nei campi definiti IDENTITY() nelle tabelle passate come parametro.

Compatibilità con SQL Server 2000.

IF OBJECT_ID('CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE', 'P') IS NOT NULL
  DROP PROCEDURE DBO.CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE
GO

CREATE PROCEDURE CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE
  (@TABLE_LIST VARCHAR(8000),
   @ENABLE SMALLINT,
   @ALLOWS_IDENTITY_INSERT SMALLINT)

AS BEGIN
 
  /*
     Descrizione   : Permette di abilitare/disabilitare i CONSTRAINT di tipo FOREIGN KEYS definiti sulle tabelle

                           contenute nella lista @TABLE_LIST

     Parametri     : @TABLE_LIST = String lista separata da virgole "," in cui elencare le tabelle interessate

                          @ENABLE = Smallint per indicare alla stored procedure se
                                              si desidera disabilitare o abilitare le FOREIGN KEYS.
                                              I valori riconosciuti sono 0 per disabilitare e -1 per
                                              abilitare le FOREIGN KEYS. Non ha default, se viene
                                              specificato un valore diverso da quelli previsti si
                                              assume by default il valore -1 (= abilitazione)

                          @ALLOWS_IDENTITY_INSERT = Smallint per indicare alla stored procedure se 
                                                                            si desidera permettere l'assegnazione di valori
                                                                            sui campi definiti IDENTITY.
                                                                            I valori riconosciuti sono 0 per NON consentire e -1 per
                                                                            consentire l'assegnazione di valori sui campi definiti
                                                                            IDENTITY. Non ha default, se viene
                                                                            specificato un valore diverso da quelli previsti si
                                                                            assume by default il valore 0 (= NON consentire)

  */

  --SET NOCOUNT ON

  DECLARE @STR_COMMAND AS VARCHAR(512),
          @STR_COMMAND_SET_IDENTITY AS VARCHAR(512),
          @STR_TABLE_NAME AS VARCHAR(128),
          @STR_TMP VARCHAR(8000)

  SET @STR_TMP = ''
 
  DECLARE CUR_DISABLE_CONSTRAINT CURSOR FOR
   
    SELECT LTRIM(RTRIM(CAST(SYSOBJECTS.NAME AS VARCHAR(128)))),

           ('SET IDENTITY_INSERT ' +
            LTRIM(RTRIM(CAST(SYSOBJECTS.NAME AS VARCHAR))) +
            CASE (@ALLOWS_IDENTITY_INSERT)
              WHEN (-1) THEN ' ON '
              WHEN (0) THEN ' OFF '
              ELSE ' OFF '
            END
           ) CMD_IDENTITY_INSERT,

           ('ALTER TABLE ' +
            LTRIM(RTRIM(CAST(SYSOBJECTS.NAME AS VARCHAR))) +
            CASE (@ENABLE)
              WHEN (-1) THEN ' WITH CHECK CHECK CONSTRAINT ' 
              WHEN (0) THEN ' NOCHECK CONSTRAINT '
              ELSE ' WITH CHECK CHECK CONSTRAINT '
            END +
            (SELECT OBJ_FK.NAME
             FROM SYSOBJECTS OBJ_FK
             WHERE OBJ_FK.ID=SYSCONSTRAINTS.CONSTID)
           ) CMD_DISABLE_CONSTRAINT
   
    FROM SYSCONSTRAINTS
    INNER JOIN SYSOBJECTS ON SYSOBJECTS.ID=SYSCONSTRAINTS.ID
    INNER JOIN SYSFOREIGNKEYS ON SYSFOREIGNKEYS.CONSTID=SYSCONSTRAINTS.CONSTID
    WHERE CHARINDEX((',' + LTRIM(RTRIM(UPPER(SYSOBJECTS.NAME))) + ','), -- Table (Es: 'TestTabA, TestTabB, TestTabG')
                    (',' + REPLACE(@TABLE_LIST, ' ', '') + ',')) > 0
    ORDER BY SYSOBJECTS.NAME,
             (SELECT OBJ_FK.NAME
              FROM SYSOBJECTS OBJ_FK
              WHERE OBJ_FK.ID=SYSCONSTRAINTS.CONSTID)

  OPEN CUR_DISABLE_CONSTRAINT

  FETCH NEXT FROM CUR_DISABLE_CONSTRAINT INTO @STR_TABLE_NAME, @STR_COMMAND_SET_IDENTITY, @STR_COMMAND
 
  WHILE (@@FETCH_STATUS = 0)
  BEGIN
    IF (@STR_COMMAND <> '')
    BEGIN
      PRINT @STR_COMMAND
      EXECUTE (@STR_COMMAND)
    END

    IF (@STR_COMMAND_SET_IDENTITY <> '') AND
       (CHARINDEX(@STR_TABLE_NAME, @STR_TMP) = 0)
    BEGIN
      PRINT @STR_COMMAND_SET_IDENTITY
      EXECUTE (@STR_COMMAND_SET_IDENTITY)
      SET @STR_TMP = @STR_TMP + ' ' + @STR_TABLE_NAME
    END
    ELSE
      PRINT '/* ' + @STR_COMMAND_SET_IDENTITY + '*/'

    FETCH NEXT FROM CUR_DISABLE_CONSTRAINT INTO @STR_TABLE_NAME, @STR_COMMAND_SET_IDENTITY, @STR_COMMAND
  END -- WHILE

  CLOSE CUR_DISABLE_CONSTRAINT
 
  DEALLOCATE CUR_DISABLE_CONSTRAINT
 
  PRINT LTRIM(RTRIM('Table string list: ' + @STR_TMP))

  --SET NOCOUNT OFF
END

Ad esempio, il comando:

EXEC CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE 'TAB_A, TAB_B', 0, -1

permette di disabilitare i foreign key constraint e permette l'assegnazione di valori ai campi IDENTITY.

Viceversa il comando:

EXEC CS_SP_ENABLE_DISABLE_FK_CONSTRAINT_ON_TABLE 'TAB_A, TAB_B', -1, 0

riprinstina l'abilitazione per foreign key constraint e impedisce l'assegnazione di valori ai campi IDENTITY.

 

Ciao !

Published martedì 19 febbraio 2008 14.49 by sgovoni

Comments

No Comments