3

我真的需要知道是否有任何方法可以将表的主键约束更改或删除为 UNIQUE 约束

当我尝试从Entreprise表中删除主要约束时:

ALTER TABLE Entreprise
DROP CONSTRAINT  PK__Entrepri__AABA1D8F1B0907CE

我收到此错误:

消息 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约束。

另一个问题是,你为什么对这样做感兴趣?

也许您可以阅读讨论此问题的其他 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 回答