sql-server - 当列被索引时,如何将列更改为 NOT NULL

标签 sql-server tsql stored-procedures indexing primary-key

我正在使用 SQL Server 2008 R2,并且编写了一个存储过程,该存储过程向数据库中多个表中的多个列添加约束。但是,我发现存储过程失败,因为由于列上有索引,它无法将特定列设置为主键。各种表中的许多列都是这种情况。

有没有办法将列更改为 NOT NULL 并将其设置为主键而不删除索引?否则,是否有一个好方法来禁用或删除索引,然后在 ALTER COLUMN 语句之后启用或重新创建索引?

最佳答案

谢谢大家的评论。经过一些研究,我能够确定如何使用 @mwigdahl 提到的确切表格动态地执行此操作。请参阅下面的代码:

DECLARE @indexName nvarchar(254),
    @tableName nvarchar(254),
    @indexType nvarchar(254),
    @columnName nvarchar(254),
    @isPadded integer,
    @ignore_dup_key integer,
    @allow_row_locks integer,
    @allow_page_locks integer,
    @fillFactor integer

SELECT
    @indexName = i.name, 
    @tableName = o.name,
    @indexType = i.type_desc,
    @columnName = co.[name],
    @isPadded = i.is_padded,
    @ignore_dup_key = i.[ignore_dup_key],
    @allow_row_locks = i.[allow_row_locks],
    @allow_page_locks = i.[allow_page_locks],
    @fillFactor = i.fill_factor
FROM sys.indexes AS i
    INNER JOIN sys.objects AS o ON i.object_id = o.object_id
    INNER JOIN sys.index_columns ic on ic.object_id = i.object_id AND ic.index_id = i.index_id
    INNER JOIN sys.columns co on co.object_id = i.object_id AND co.column_id = ic.column_id
WHERE
    i.[type] = 2 AND
    o.[type] = 'U'

DECLARE @sql varchar(max)

SET @sql = 'DROP INDEX [' + @indexName + '] ON [' + @tableName + ']'

EXEC (@sql)

PRINT 'Dropped Index'

-- Do work here

DECLARE @pad_index nvarchar(3),
    @ignore_dup nvarchar(3),
    @row_locks nvarchar(3),
    @page_locks nvarchar(3)

IF @isPadded = 0 SET @pad_index = 'OFF'
ELSE SET @pad_index = 'ON'

IF @ignore_dup_key = 0 SET @ignore_dup = 'OFF'
ELSE SET @ignore_dup = 'ON'

IF @allow_row_locks = 0 SET @row_locks = 'OFF'
ELSE SET @row_locks = 'ON'

IF @allow_page_locks = 0 SET @page_locks = 'OFF'
ELSE SET @page_locks = 'ON'

SET @sql = 'CREATE ' + @indexType + ' INDEX [' + @indexName + '] ON [' + @tableName + ']' + 
    '(' + 
    '[' + @columnName + '] ASC' + 
    ') WITH (' + 
    'PAD_INDEX = ' + @pad_index + ',' + 
    'STATISTICS_NORECOMPUTE = OFF,' + 
    'SORT_IN_TEMPDB = OFF,' + 
    'IGNORE_DUP_KEY = ' + @ignore_dup + ',' + 
    'DROP_EXISTING = OFF,' + 
    'ONLINE = OFF,' + 
    'ALLOW_ROW_LOCKS = ' + @row_locks + ',' + 
    'ALLOW_PAGE_LOCKS = ' + @page_locks + ',' + 
    'FILLFACTOR = ' + CONVERT(nvarchar(100),@fillFactor) + ')' + 
    'ON [PRIMARY]'

PRINT @sql

EXEC (@sql)

PRINT 'Created Index'

我使用 SSMS 中的Script Index As 函数来查看如何在 T-SQL 中创建索引。

然后,我查询了 sys.indexessys.index_columns 表以确定哪些属性可用。

代码显示了对这些表的查询,将这些属性保存到变量,然后删除并重新创建索引。有一些选项在这些表中不可用,我必须对其进行硬编码。有谁知道这些选项在系统表中的某个位置是否可用?

我希望这对将来的其他人有帮助。

关于sql-server - 当列被索引时,如何将列更改为 NOT NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8661326/

相关文章:

SQL:如何从重复行中选择第一条记录?

sql-server - 如何根据 ssrs 中的特定值将数据集中的数据拆分为 2 个表

javascript - 雪花和存储过程我们如何循环保存在内部阶段中的文件行?

php - SELECT INTO 还是存储过程?

javascript - 使用 Snowflake 中的任务调用存储过程

sql-server - 使 UDF 独立于 DATEFIRST 设置

mysql - 等效于 MySQL ON DUPLICATE KEY UPDATE in Sql Server

tsql - 将表变量传递到动态SQL 2008中

sql - SQL中的动态间隔创建

mysql - SQL Server 中 Mysql 的 SHOW INDEX 替代方案是什么?