将主键添加到数据库中的一些现有表

Adding primary key to some exising tables in a database

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

1.遍历所有表
2.select没有主键的
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

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

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);  

对于已经定义了标识列的 table,您可以使用此查询将此标识列设置为主键(因为您不能在同一个 table)

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);