【问题标题】:Loop through all tables in a database and insert a row based on the column data type in SQL Server循环遍历数据库中的所有表,并根据 SQL Server 中的列数据类型插入一行
【发布时间】:2017-10-17 09:49:15
【问题描述】:

我希望能够遍历数据库中的所有表并找出每个表的数据类型和长度。如果数据类型是 int ,我必须在该列中插入 0 ,如果该列是 String 并且长度小于 30 ,则插入 'UKN' 或如果该列是 String 并且大于 30 插入为 'UnKnown'。

如何编写一个循环遍历所有表并根据条件插入数据库的脚本? 对于特定的表如何取每一列和相关的数据类型并检查?

【问题讨论】:

    标签: sql-server database cursor


    【解决方案1】:

    您可以使用information_schema.columns系统视图,无需担心CURSOR

    USE <DATABASE_NAME>
    GO
    
    SELECT C.TABLE_CATALOG
         , C.TABLE_SCHEMA
         , C.TABLE_NAME
         , C.COLUMN_NAME
         , C.DATA_TYPE
         , C.CHARACTER_MAXIMUM_LENGTH
        , CASE
            WHEN C.DATA_TYPE = 'int' THEN '0' 
            WHEN C.DATA_TYPE IN ('char', 'nchar', 'varchar', 'nvarchar') 
            THEN 
                CASE
                    WHEN C.CHARACTER_MAXIMUM_LENGTH <30 then 'UKN' 
                    ELSE 'UnKnown' 
                END 
            END 'OUTPUTFROM'
    FROM
        information_schema.columns  C
    ORDER BY 
        TABLE_NAME
    

    插入

    ;WITH cteX
    AS(
        SELECT C.TABLE_CATALOG
             , C.TABLE_SCHEMA
             , C.TABLE_NAME
             , C.COLUMN_NAME
             , C.DATA_TYPE
             , C.CHARACTER_MAXIMUM_LENGTH
            , CASE
                WHEN C.DATA_TYPE = 'int' THEN '0' 
                WHEN C.DATA_TYPE IN ('char', 'nchar', 'varchar', 'nvarchar') 
                THEN 
                    CASE
                        WHEN C.CHARACTER_MAXIMUM_LENGTH <30 then 'UKN' 
                        ELSE 'UnKnown' 
                    END 
                END 'OUTPUTFROM'
        FROM
            information_schema.columns  C
    )
    INSERT INTO dbo.TABLE 
        ( database_name, table_schema, table_name, column_name, Output_from)
    SELECT
        TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, OUTPUTFROM
    FROM 
        cteX X
    

    更新

    ;WITH cteX
    AS(
        SELECT C.TABLE_CATALOG
             , C.TABLE_SCHEMA
             , C.TABLE_NAME
             , C.COLUMN_NAME
             , C.DATA_TYPE
             , C.CHARACTER_MAXIMUM_LENGTH
            , CASE
                WHEN C.DATA_TYPE = 'int' THEN '0' 
                WHEN C.DATA_TYPE IN ('char', 'nchar', 'varchar', 'nvarchar') 
                THEN 
                    CASE
                        WHEN C.CHARACTER_MAXIMUM_LENGTH <30 then 'UKN' 
                        ELSE 'UnKnown' 
                    END 
                END 'OUTPUTFROM'
        FROM
            information_schema.columns  C
    )
    UPDATE
        T
    SET
        T.OUTPUTFROM = X.OUTPUTFROM
    FROM 
        dbo.TABLE T
    INNER JOIN 
        cteX X ON   X.TABLE_CATALOG = T.database_name 
                AND X.TABLE_SCHEMA = T.table_schema
                AND X.table_name = T.table_name
                AND X.column_name = T.column_name
    

    【讨论】:

    • 如何为这些表的列插入“OUTPUTFROM”值?
    • 请显示要插入的表格是什么样的
    • 不确定您的表格是什么样的,但我已经更新了答案以显示插入或更新的可能选项
    • 在您的脚本中返回所有表中的所有列。我想为我在数据库中具有 0 和“未知”值的所有表插入一行。
    • 实际情况是在我的数据仓库数据库中,我必须插入第一行作为所有维度表的已知值,而不是事实表。 bcz 我的数据仓库中有 100 多个维度表。所以不能手动运行很多脚本。
    【解决方案2】:

    使用系统表:

    select    t.name as TableName
            , c.name as ColumnName
            , ty.name as [DataType]
            , case  when ty.name = 'int' then '0' 
                    when ty.name in ('char', 'nchar', 'varchar', 'nvarchar') 
                        then case   when c.max_length <30 then 'UKN' 
                                    else 'UnKnown' end 
               end as OUTPUT
    from sys.tables t
    inner join sys.columns c on t.object_id = c.object_id
    inner join sys.types ty on ty.user_type_id = c.user_type_id
    where t.type = 'U'
    

    【讨论】:

      猜你喜欢
      • 2017-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      相关资源
      最近更新 更多