首页 > 解决方案 > SQL Server:删除所有数据库表中的所有 Not Null 约束

问题描述

如何使用 SQL Server 在每个表的所有列中删除所有 Not Null 约束?

想在所有表和列中循环运行此查询, 如何使用查询删除 sql server 中的非空约束

注意:要求适用于所有非主键列。

类似问题:

如何删除所有表中的所有外键约束?

标签: sqlsql-serverazure-sql-databasesql-server-2016

解决方案


您可以使用以下查询为每列生成更改语句。并使用生成的语句来更改表。这不会改变主键列,但不会考虑其他外键约束。

DECLARE @Sql NVARCHAR(MAX) = ''

SELECT @Sql +=  CONCAT(N'ALTER TABLE '
, QUOTENAME(schema_name(t.schema_id))
, N'.', QUOTENAME(t.name) 
, N' ALTER COLUMN '
, QUOTENAME(c.Name
), N' '
,Type_name(c.user_type_id) + CASE 
        --types without length, precision, or scale specifiecation 
        WHEN Type_name(c.user_type_id) IN (
                N'int'
                ,N'bigint'
                ,N'smallint'
                ,N'tinyint'
                ,N'money'
                ,N'smallmoney'
                ,N'real'
                ,N'datetime'
                ,N'smalldatetime'
                ,N'bit'
                ,N'image'
                ,N'text'
                ,N'uniqueidentifier'
                ,N'date'
                ,N'ntext'
                ,N'sql_variant'
                ,N'hierarchyid'
                ,N'geography'
                ,N'geometry'
                ,N'timestamp'
                ,N'xml'
                )
            THEN N''
                --types with precision and scale specification 
        WHEN Type_name(c.user_type_id) IN (
                N'decimal'
                ,N'numeric'
                )
            THEN N'(' + Cast(c.PRECISION AS VARCHAR(5)) + N',' + Cast(c.scale AS VARCHAR(5)) + N')'
                --types with scale specification only 
        WHEN Type_name(c.user_type_id) IN (
                N'time'
                ,N'datetime2'
                ,N'datetimeoffset'
                )
            THEN N'(' + Cast(c.scale AS VARCHAR(5)) + N')'
                --float default precision is 53 - add precision when column has a different precision value 
        WHEN Type_name(c.user_type_id) IN (N'float')
            THEN CASE 
                    WHEN c.PRECISION = 53
                        THEN N''
                    ELSE N'(' + Cast(c.PRECISION AS VARCHAR(5)) + N')'
                    END
                --types with length specifiecation 
        ELSE N'(' + CASE ic.CHARACTER_MAXIMUM_LENGTH
                WHEN -1
                    THEN N'MAX'
                ELSE Cast(ic.CHARACTER_MAXIMUM_LENGTH AS NVARCHAR(20))
                END + N')'
        END + CASE 
        WHEN c.is_filestream = 1
            THEN N' FILESTREAM'
        ELSE N''
        END + COALESCE(N' COLLATE ' + c.collation_name, N'') + CASE 
        WHEN c.is_sparse = 1
            THEN N' SPARSE'
        ELSE N''
        END + CASE 
        WHEN c.is_rowguidcol = 1
            THEN N' ROWGUIDCOL'
        ELSE N''
        END
, N' NULL', '
GO
'  )
FROM sys.tables t
INNER JOIN sys.columns c on c.object_Id = t.object_Id
INNER JOIN INFORMATION_SCHEMA.COLUMNS  ic on ic.TABLE_SCHEMA = Schema_name(t.schema_id)
    AND ic.TABLE_NAME = t.name
    AND ic.COLUMN_NAME = c.name
WHERE c.is_nullable = 0
-- And is not part of the primary key
AND NOT EXISTS (
    SELECT 1
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS cons
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON cons.TABLE_NAME = K.TABLE_NAME
        AND cons.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
        AND cons.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
        AND cons.CONSTRAINT_NAME = K.CONSTRAINT_NAME
    WHERE cons.CONSTRAINT_TYPE = 'PRIMARY KEY'
    AND k.COLUMN_NAME = c.Name
    AND k.TABLE_NAME = t.Name
    AND k.TABLE_SCHEMA = ic.TABLE_SCHEMA
)


-- PRINT(@SQL)
-- Execute the generated alter table statements
EXEC (@SQL)


推荐阅读