3

テーブルの主キー制約をUNIQUE制約に変更または削除できる方法があるかどうかを本当に知る必要があります

Entrepriseテーブルから主拘束を削除しようとすると、次のようになります。

ALTER TABLE Entreprise
DROP CONSTRAINT  PK__Entrepri__AABA1D8F1B0907CE

このエラーが発生します:

Msg 3725、レベル16、状態0、行1
制約「PK_Entrepri _AABA1D8F1B0907CE」は、テーブル「Dossier」、外部キー制約「Cle_FDOs」によって参照されています。
メッセージ3727、レベル16、状態0、行1
制約を削除できませんでした。以前のエラーを参照してください。

dossierだから問題は私がテーブルの行を削除したくないということです

これはEntreprise表です:

create table Entreprise
(
    ID_Entreprise integer ,
    Raison_Social varchar(100),/*Nom Entreprise*/
    Num_Raison_Sociale varchar(20) unique ,
    Adress varchar(100),
    Abreviation varchar(10),
    CNSS_Entreprise integer unique,
    Eligible varchar(20),/*AUTOMATIQUE par raport aux CNSS_Entreprise*/
    Effectif integer,/*NB SALARIE*/
    Ville varchar(20),
    Responsable varchar(20),
    EMAIL_Responsable varchar(20),
    Tel_Responsable varchar(20),
    Fax_Responsable varchar(20),    
    Directeur varchar(20),
    EMAIL_Directeur varchar(20),
    Tel_Directeur varchar(20),
    Fax_Directeur varchar(20),
    RIB varchar(60),/*ici non sur le dossier lo*/
    Nom_Giac varchar(50) foreign key references GIAC(Nom_Giac),
    primary key(Nom_Giac,ID_Entreprise)
)
GO

そしてこれはDossier表です:

create table Dossier
(
    ID_Dossier integer primary key,
    ID_Entreprise int,/*AUTOMATIQE par rapotrt aux la cnss de l'entreprise qui l'a donne*/
    Date_Depot datetime ,
    Type_Etude varchar(2),/*DS IF combobox*/
    Dernier_Type varchar(2),/* AUTOMATIQUE */
    Eligibile varchar(3),/*  par raport aux Dernier Type et CNSS et COTISTAION EXERCICES */
    Fiche_Information varchar(3),/*checkbox o/n */
    Buletin_Adhesion varchar(3),
    Fiche_Renseignment varchar(3),
    Attestation varchar(3),
    Date_Debut datetime,
    Date_Fin datetime,
    --Etat_Dossier varchar(3), /* hado m7aydine mn war9a*/
    --Motif text,/*en cas de rejet, peu prendre null apart le cnss et cotisation ex et dernier formation *//* hado m7aydine mn war9a*/
    ID_Cabinet integer foreign key references Cabinet(ID_Cabinet),
    Montant_Demander decimal(6,2),
    Duree integer,
    Porcentage_Taux varchar(3), /* combobox 70% 80% */
    Nom_Giac varchar(50),
    constraint Cle_FDOs foreign key(Nom_Giac,ID_Entreprise) references Entreprise(Nom_Giac,ID_Entreprise),
)
GO
4

3 に答える 3

2

単一のSQL命令で「変更」を自動的に行うことはできませんが、必要に応じてそれを実現できます。

Enterpriseまず、具体的なケースでは、参照されているテーブルへの参照を含むテーブルの外部キーを削除する必要があります。

から外部キーをDossier削除してから、から主キーを削除して、制約Enterpriseを作成する必要があります。UNIQUE

もう1つの質問は、なぜそれを行うことに興味があるのか​​ということです。

たぶん、あなたはこの問題について議論しているこの他のSOスレッドを読むことができます。

于 2012-09-04T22:42:10.633 に答える
1

エラーが示唆しているので、最初に外部キー参照を削除する必要があります。これはのレコードを削除しませんDossier(私のSQL Fiddleのを参照してください)。

ALTER TABLE Dossier DROP CONSTRAINT Cle_FDOs;
于 2012-09-04T22:40:08.513 に答える
1

私はこの問題に何度か遭遇し、主キーの制約を受けて一意のインデックスに変換できるストアドプロシージャを作成することになりました。問題のテーブルを参照するものをすべて削除して再作成します(これは、高度に参照されるテーブルのトリッキーな部分です)。

マルチパートの主キーを処理できます。

CREATE PROCEDURE spPrimaryKeyToUniqueKey
    @schema VARCHAR(255),
    @tableName VARCHAR(255)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @constraintsToDrop NVARCHAR(MAX) = '';
    DECLARE @constraintsToCreate NVARCHAR(MAX) = '';
    DECLARE @indexesToDrop NVARCHAR(MAX) = '';
    DECLARE @indexesToCreate NVARCHAR(MAX) = '';

    ;WITH _fks AS (
        SELECT  
          FkName               = fk.[name]
        , SchemaName           = sch.[name] 
        , TableName            = tab1.[name]
        , ColumnName           = col1.[name]
        , ReferencedSchema     = sch2.[name]
        , ReferencedTableName  = tab2.[name]
        , ReferencedColumnName = col2.[name]
        , ReferencedColOrder   = ic.key_ordinal
        FROM sys.foreign_key_columns fkc
        JOIN sys.foreign_keys fk ON fk.object_id = fkc.constraint_object_id
        JOIN sys.tables tab1 ON tab1.object_id = fkc.parent_object_id
        JOIN sys.schemas sch ON tab1.schema_id = sch.schema_id
        JOIN sys.columns col1 ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
        JOIN sys.tables tab2 ON tab2.object_id = fkc.referenced_object_id
        JOIN sys.schemas sch2 ON sch2.schema_id = tab2.schema_id
        JOIN sys.columns col2 ON col2.column_id = fkc.referenced_column_id AND col2.object_id = tab2.object_id
        JOIN sys.indexes i ON fk.key_index_id = i.index_id AND i.object_id = tab2.object_id
        JOIN sys.index_columns ic ON col2.column_id = ic.column_id AND ic.object_id = tab2.object_id AND i.index_id = ic.index_id
    ) 
    , _fksWithColList AS (
        SELECT
          f.FkName    
        , f.SchemaName
        , f.TableName 
        , f.ReferencedSchema
        , f.ReferencedTableName
        , TableColNameList = STUFF(
           (SELECT  ',[' + ff.ColumnName + ']'
            FROM _fks ff
            WHERE f.FkName = ff.FkName AND f.SchemaName = ff.SchemaName AND f.TableName = ff.TableName AND f.ReferencedSchema = ff.ReferencedSchema AND f.ReferencedTableName = ff.ReferencedTableName
            ORDER BY ff.ReferencedColOrder
            FOR XML PATH('')), 1, 1, '')
        , ReferencedTableColNameList = STUFF(
           (SELECT  ',[' + ff.ReferencedColumnName + ']'
            FROM _fks ff
            WHERE f.FkName = ff.FkName AND f.SchemaName = ff.SchemaName AND f.TableName = ff.TableName AND f.ReferencedSchema = ff.ReferencedSchema AND f.ReferencedTableName = ff.ReferencedTableName
            ORDER BY ff.ReferencedColOrder
            FOR XML PATH('')), 1, 1, '')
        FROM _fks f
        GROUP BY f.FkName, f.SchemaName, f.TableName, f.ReferencedSchema, f.ReferencedTableName
    ) 
    , _commands AS (
        SELECT *, 
          DropStatement   = REPLACE(REPLACE(REPLACE('ALTER TABLE [{0}].[{1}] DROP CONSTRAINT IF EXISTS [{2}];', 
            '{0}', SchemaName), 
            '{1}', TableName),
            '{2}', FkName),
          CreateStatement = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('ALTER TABLE [{0}].[{1}] DROP CONSTRAINT IF EXISTS [{2}]; ALTER TABLE [{0}].[{1}] ADD CONSTRAINT [{2}] FOREIGN KEY ({3}) REFERENCES [{4}].[{5}]({6});',
            '{0}', SchemaName), 
            '{1}', TableName),
            '{2}', FkName),
            '{3}', TableColNameList),
            '{4}', ReferencedSchema),
            '{5}', ReferencedTableName),
            '{6}', ReferencedTableColNameList)
        FROM _fksWithColList
        WHERE ReferencedSchema = @schema AND ReferencedTableName = @tableName
    )
    SELECT @constraintsToDrop = @constraintsToDrop + DropStatement + CHAR(13)+CHAR(10), @constraintsToCreate = @constraintsToCreate + c.CreateStatement + CHAR(13)+CHAR(10)
    FROM _commands c

    ;WITH _indexes AS (
        SELECT 
          TableName  = t.[name]
        , SchemaName = s.[name]
        , IndexName  = i.[name]
        , ColumnName = c.[name]
        , ColOrder   = ic.key_ordinal
        , ColDesc    = ic.is_descending_key
        FROM sys.tables t
        JOIN sys.schemas s ON t.schema_id = s.schema_id
        JOIN sys.indexes i ON t.object_id = i.object_id        
        JOIN sys.columns c ON t.object_id = c.object_id
        JOIN sys.index_columns ic ON t.object_id = ic.object_id AND c.column_id = ic.column_id AND i.index_id = ic.index_id
        WHERE s.[name] = @schema AND t.[name] = @tableName AND i.is_primary_key = 1
    )
    , indexesWithColList AS (
        SELECT 
          TableName 
        , SchemaName
        , IndexName 
        , IndexColList = STUFF(
           (SELECT  ',[' + ii.ColumnName + ']' + IIF(ii.ColDesc = 1, ' DESC', '')
            FROM _indexes ii
            WHERE i.TableName = ii.TableName AND i.SchemaName = ii.SchemaName AND i.IndexName = ii.IndexName  AND ii.ColOrder > 0
            ORDER BY ii.ColOrder
            FOR XML PATH('')), 1, 1, '')
        , IndexColNameList = STUFF(
           (SELECT  '_' + ii.ColumnName
            FROM _indexes ii
            WHERE i.TableName = ii.TableName AND i.SchemaName = ii.SchemaName AND i.IndexName = ii.IndexName  AND ii.ColOrder > 0
            ORDER BY ii.ColOrder
            FOR XML PATH('')), 1, 1, '')
        FROM _indexes i
        GROUP BY i.TableName, i.SchemaName, i.IndexName
    ) 
    , _commands AS (
        SELECT *,
          DropStatement   = REPLACE(REPLACE(REPLACE('ALTER TABLE [{0}].[{1}] DROP CONSTRAINT {2};', 
            '{0}', i.SchemaName),
            '{1}', i.TableName),
            '{2}', i.IndexName),
          CreateStatement = REPLACE(REPLACE(REPLACE(REPLACE('CREATE UNIQUE NONCLUSTERED INDEX [{0}] ON [{1}].[{2}] ({3});',
            '{0}', 'UX_' + i.SchemaName + '_' + i.TableName + '_' + i.IndexColNameList),
            '{1}', i.SchemaName),
            '{2}', i.TableName),
            '{3}', i.IndexColList)
        FROM indexesWithColList i
    ) 
    SELECT @indexesToDrop = @indexesToDrop + c.DropStatement + CHAR(13)+CHAR(10), @indexesToCreate = @indexesToCreate + c.CreateStatement + CHAR(13)+CHAR(10)
    FROM _commands c


    DECLARE @sql NVARCHAR(MAX);
    SET @sql = REPLACE(REPLACE(REPLACE(REPLACE('
SET XACT_ABORT ON;

BEGIN TRAN t1

--Drop foreign keys
{0}

--Drop indexes
{1}

--Create indexes
{2}

--Recreate foreign keys
{3}

COMMIT TRAN t1
',
    '{0}', @constraintsToDrop),
    '{1}', @indexesToDrop),
    '{2}', @indexesToCreate),
    '{3}', @constraintsToCreate);

    PRINT @sql;

    EXEC sp_executesql @sql
END
GO
于 2019-11-29T21:42:14.483 に答える