MSSQL:一般来说,alter column not null
在Microsoft SQL Server 2008 R2中,我想将可空列更改为不为空。 很明显,我可以通过重申数据类型来做到这一点
alter table t alter column c int not null
例如,如果列tc是int数据类型。 但是一般情况下,如果不重申现有的数据类型呢? 我正在寻找相当的一些
alter table t alter column c not null
现有数据类型保留在原位,并且仅关闭可空性。
背景
我已经对我的数据库进行了审计,发现很多情况下,列被指定为可为空,但在实践中不会出现空值。 我想收紧架构来禁止这些列中的空值。 手动将DDL写入每个“更改列”是容易出错的,因为我可能会得到错误的数据类型。 我可以通过使用一个schema-dumper程序自动生成代码,该程序输出每列的现有数据类型,但如果自定义程序不知道最新的数据类型并输出其他内容,也会有风险(例如,假设它不知道datetime2而是写出datetime)。
SQL服务器已经知道列的类型是什么,所以肯定有办法告诉它保持这一点,只是关闭可空性。
如果除了找到现有的数据类型将其放入DDL,实际上没有办法做到这一点,也许您可以推荐一个合适的工具来使用它? 我知道Sybase时代的dbschema.pl,但可能会有更现代的东西,或者一些熟知的SQL片段,它们会从模式视图中打印出必要的语句。
两种方法:
1)在这个答案上展开以考虑max_length,precision,scale和collation_name。 如果你有多个模式,你也需要适应。
SELECT
'ALTER TABLE '
+QUOTENAME(aud.[table_name])
+' ALTER COLUMN '
+QUOTENAME(aud.[column_name])
+TYPE_NAME([system_type_id])
+' NOT NULL;'
FROM MyColumnAuditList aud
INNER JOIN sys.columns col ON (
col.[object_id] = OBJECT_ID(aud.[table_name]) AND
col.[name] = aud.[column_name]
)
2)在SSMS中,右键单击数据库并选择'Script Database As'。 使用您选择的文本分析工具从结果中提取列定义。
Anon提出的“两种方法”答案很有帮助。 该网站的评论框不允许有足够的文字,所以我会在这里发表我的最终答案。
链接的答案对用户数据类型有特殊的规定,这是我的数据库没有的,所以我使用type_name
builtin代替。 此查询尝试反向设计每列的类型:
select t.name,
c.name,
case
when type_name(c.system_type_id) in (
'int', 'real', 'float', 'date', 'time', 'datetime', 'datetime2',
'tinyint', 'smallint', 'smalldatetime', 'bit', 'bigint', 'timestamp',
'image'
) then type_name(c.system_type_id)
else type_name(c.system_type_id) + '('
+ case
when precision = 0 then convert(varchar(10), c.max_length)
else convert(varchar(10), precision) + ', ' + convert(varchar(10), scale)
end
+ ')'
end as ty
from sys.tables t
join sys.columns c
on t.object_id = c.object_id
where c.is_nullable = 1
and c.is_computed = 0
and t.schema_id = 1
order by t.name,
c.name
然后,可以从该查询中获取每行,并在运行“alter table”之前检查是否存在空值。 我正在做类似以下的事情:
select case when
exists (select 0 from TABLE)
and not exists (select 0 from TABLE tablesample (1000 rows) where COLUMN is null)
then 1 else 0 end
对于每个TABLE,由第一个查询返回的COLUMN。 如果第二个查询返回1,那么你可能会改变'alter table'。 我使用上面的tablesample来阻止这个数据库太重,因为我打算定期运行检查; 如果由sp_spaceused返回的表的大小小于100千字节,那么我省略tablesample子句。
或者,如果你感到勇敢,你可以运行所有的'alter table'语句,如果列中包含空值,就让它们失败。
奇怪的是,我没有权限在数据库上右键单击Management Studio和“脚本数据库为”,尽管我可以为单个对象执行此操作。
链接地址: http://www.djcxy.com/p/13325.html