【问题标题】:SQL Server: Drop all Not Null constraints in all DB tablesSQL Server:删除所有数据库表中的所有 Not Null 约束
【发布时间】:2020-09-11 19:42:09
【问题描述】:

如何使用 SQL Server 删除每个表的所有列中的所有非空约束?

希望在所有表和列中循环运行此查询, How to remove not null constraint in sql server using query

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

类似问题:

How to drop all Foreign Key constraints in all tables?

【问题讨论】:

  • 是列的属性,而不是约束。这可能不适用于设计正确的数据库,因为主键列不能为空。这闻起来像一个很大的XY problem。一个起点可能是使用sys.columns 来查找可为空的列。
  • 嗨 @SMor 要求适用于所有非主键
  • 嗨 @SMor 我认为 not null 是一个约束,正在阅读这里,w3schools.com/sql/sql_notnull.asp
  • 正如@SMor 所说,查看 sys.columns 和相关表以找出表的现有定义。然后,您可以构造根据需要更改表列的 ALTER TABLE 语句。这可能会产生许多副作用。查询我依赖数据中没有空值。此外,这些列上的唯一索引将防止(多个)行具有空值。

标签: sql sql-server azure-sql-database sql-server-2016


【解决方案1】:

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

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)

【讨论】:

    猜你喜欢
    • 2013-12-07
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多