【问题标题】:Adding primary key to some exising tables in a database向数据库中的某些现有表添加主键
【发布时间】:2015-06-11 01:17:56
【问题描述】:

我有一个包含 600 多个表的数据库。有些表有主键,有些没有。我怎样才能动态:

1. 遍历所有表
2. 选择没有主键的
3. 添加一个自增字段
4. 将此字段设为主键

我认为这将是以下几种情况的组合:

USE MyDataBase; 
GO
-- List all tables without primary constraint
SELECT i.name AS IndexName, 
    OBJECT_NAME(ic.OBJECT_ID) AS TableName, 
    COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id
WHERE i.is_primary_key = 0
GO

-- add new auto incremented field
ALTER TABLE MyTable 
ADD PK_ID BIGINT IDENTITY;
GO

-- create new primary key constraint
ALTER TABLE MyTable 
ADD CONSTRAINT PK_ID PRIMARY KEY NONCLUSTERED (PK_ID);
GO

【问题讨论】:

    标签: sql sql-server database for-loop primary-key


    【解决方案1】:

    此查询将排除所有具有主键或标识列的表,然后在剩余对象上添加标识列和主键

    DECLARE @PKScript AS VARCHAR(max) = '';
    SELECT @PKScript += 
        '  ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(obj.SCHEMA_ID))+'.'+ QUOTENAME(obj.name) + 
                          ' ADD PK_ID BIGINT IDENTITY;' +
         ' ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(obj.SCHEMA_ID))+'.'+QUOTENAME(obj.name) + 
                         ' ADD CONSTRAINT PK_ID_' + obj.name+ ' PRIMARY KEY NONCLUSTERED (PK_ID) '
     FROM sys.objects obj
     WHERE object_id not in
         (select parent_object_id
          from sys.key_constraints 
          where type = 'PK'
          UNION
          Select object_id
          from sys.identity_columns
          )
          AND type = 'U'
    --PRINT (@PKScript);
    EXEC(@PKScript);  
    

    对于已经定义了标识列的表,你可以使用这个查询将这个标识列设置为主键(因为你不能在同一个表上有两个标识列)

    DECLARE @PKScript2 VARCHAR(max)='';
    
    SELECT @PKScript2 += ' ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(obj.SCHEMA_ID))+'.'+
           QUOTENAME(obj.name) + ' ADD CONSTRAINT PK_' + icol.name +'_'+ obj.name+
           ' PRIMARY KEY NONCLUSTERED (' + QUOTENAME(icol.name) + ')' + CHAR(13)
    FROM sys.identity_columns icol INNER JOIN 
         sys.objects obj on icol.object_id= obj.object_id
    WHERE NOT EXISTS (SELECT * FROM sys.key_constraints k
                      WHERE k.parent_object_id = obj.object_id
                            AND k.type = 'PK')
          AND obj.type = 'U'
    --PRINT (@PKScript2);
    EXEC(@PKScript2);   
    

    【讨论】:

    • 非常感谢阿拉。我会试试这个。但是,似乎我需要对那些具有现有标识列但没有主键的表运行单独的查询?
    • @amindomeniko 请查看我更新的答案以涵盖这两种情况。我什至更新了第一个查询以删除一些不必要的代码。
    • 对于第一个查询,where 子句不返回任何内容。这意味着所有表都必须有一个标识键,这意味着它们应该属于第二个查询。至于第二个查询,它运行并打印出脚本,但不采取行动。
    • @amindomeniko 刚刚意识到我在选择中使用PKScript2 时错过了@。它现在应该可以工作了。
    • 很好地抓住了@amindomeniko。因为我排除了所有具有键约束的对象并且忘记提及它必须是“PK”类型。我刚刚在 NOT EXISTS 之后的内部查询中添加了这个条件。
    猜你喜欢
    • 2019-03-23
    • 1970-01-01
    • 2020-06-16
    • 2012-11-25
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    相关资源
    最近更新 更多