首页 > 解决方案 > 循环遍历表以动态创建表结构

问题描述

我有一个元数据表,它有四列 Table_N、Column_N、DType 和 DLength,我试图遍历元数据表,并为每个不同的表动态地吐出 CREATE TABLE 语句及其所有列、数据类型和数据长度。基本上是典型的表结构或定义。

到目前为止,我已经添加了一个游标来循环它们并使用动态 SQL 语法遇到障碍,特别是处理 DLength 字段的某些列值的 NULL 值。例如,如果列的数据类型是 DATE,那么该列的 Dlength 值将为 NULL。如果我连接一个列,其中 DType 为 VARCHAR,DLength为100,则 ' @DT ' + '(' + @DL+ ')' 将导致 VARCHAR(100) 但使用 DATE、INT 或任何类似的数据类型,我需要一个不同的方法。另外,不是光标的忠实粉丝,所以如果您对此有完全不同的方法,请随时提出建议。任何建议都非常感谢。谢谢!

表名:DDC_Loop(下面的示例带有 2 个表元数据)

Table_N         Column_N    DType       DLength
--------------------------------------------------------
AUT_C_TABLOG    ORIGINAL    VARCHAR             1
AUT_C_TABLOG    PROTOCOL    VARCHAR             1
AUT_C_TABLOG    TABNAME         VARCHAR            30
ANLA             GEGST          VARCHAR             8
ANLA             GPLAB            DATE             NULL
ANLA             GRBLT          VARCHAR             5
ANLA             GRBND          VARCHAR             5
ANLA             KTOGR          VARCHAR             8
ANLA             LAND1          VARCHAR             3
ANLA             MENGE          NUMERIC           16,3

标签: sql-servertsqldynamic-sql

解决方案


您可以尝试生成动态语句并执行该语句。这里需要的是为每个不同的表名对行进行编号,然后,当行号为 1 时,包含CREATE TABLE部分 SQL 语句。

-- Table
CREATE TABLE #DDC_Loop (
    Table_N nvarchar(100),         
    Column_N nvarchar(100),    
    DType nvarchar(100),       
    DLength nvarchar(100)
)
INSERT INTO #DDC_Loop
    (Table_N, Column_N, DType, DLength)
VALUES
    ('AUT_C_TABLOG', 'ORIGINAL', 'VARCHAR', '1'),
    ('AUT_C_TABLOG', 'PROTOCOL', 'VARCHAR', '1'),
    ('AUT_C_TABLOG', 'TABNAME',  'VARCHAR', '30'),
    ('ANLA',         'GEGST',    'VARCHAR', '8'),
    ('ANLA',         'GPLAB',    'DATE',    NULL),
    ('ANLA',         'GRBLT',    'VARCHAR', '5'),
    ('ANLA',         'GRBND',    'VARCHAR', '5'),
    ('ANLA',         'KTOGR',    'VARCHAR', '8'),
    ('ANLA',         'LAND1',    'VARCHAR', '3'),
    ('ANLA',         'MENGE',    'NUMERIC', '16,3')

-- Dynamci statement
DECLARE @stm nvarchar(max)
SET @stm = N''
;WITH cte AS (
    SELECT 
        Table_N, 
        Column_N, 
        DType, 
        DLength,
        ROW_NUMBER() OVER (PARTITION BY Table_N ORDER BY Table_N) RN,
        CASE 
            WHEN DLength IS NULL THEN N', ' + Column_N + N' ' + DType
            ELSE N', ' + Column_N + N' ' + DType + N'(' + DLength + N')'
        END ColumnDefinition
    FROM #DDC_Loop
)
SELECT 
    @stm = @stm + 
    CASE 
        WHEN RN = 1 THEN N'); CREATE TABLE ' + Table_N + N'(' + STUFF(ColumnDefinition, 1, 2, N'')
        ELSE ColumnDefinition
    END
FROM cte
ORDER BY Table_N, RN
SET @stm = STUFF(@stm, 1, 3, N'') + SUBSTRING(@stm, 1, 3)

-- Print and execute statement
PRINT @stm
EXEC (@stm)

生成的语句:

CREATE TABLE ANLA(GEGST VARCHAR(8), GPLAB DATE, GRBLT VARCHAR(5), GRBND VARCHAR(5), KTOGR VARCHAR(8), LAND1 VARCHAR(3), MENGE NUMERIC(16,3)); 
CREATE TABLE AUT_C_TABLOG(ORIGINAL VARCHAR(1), PROTOCOL VARCHAR(1), TABNAME VARCHAR(30)); 

推荐阅读