Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 循环表中的表以动态创建表结构_Sql Server_Tsql_Dynamic Sql - Fatal编程技术网

Sql server 循环表中的表以动态创建表结构

Sql server 循环表中的表以动态创建表结构,sql-server,tsql,dynamic-sql,Sql Server,Tsql,Dynamic Sql,我有一个元数据表,它有四列table\N、Column\N、DType和dllength,我试图循环遍历元数据表,并为每个不同的表动态地抛出CREATE table语句及其所有列、数据类型和数据长度。基本上是典型的表结构或定义 到目前为止,我已经添加了一个游标来循环遍历它们,并使用动态SQL语法遇到了一个障碍,特别是处理DLENGHT字段的某些列的值的空值。例如,如果列的数据类型是say DATE,则该列的Dlength值将为NULL。如果我连接一个列,其中VARCHAR表示DType,100表

我有一个元数据表,它有四列table\N、Column\N、DType和dllength,我试图循环遍历元数据表,并为每个不同的表动态地抛出CREATE table语句及其所有列、数据类型和数据长度。基本上是典型的表结构或定义

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

表名称:DDC_循环(下面的示例包含2个表元数据)


使用一个通用的表表达式lag、lead、几个case-epxpressions和for-xml-path,您可以将整个表内容的create-table语句作为一个长字符串返回

首先,创建并填充示例表(请在以后的问题中保存此步骤)

然后,使用cte获取滞后和超前表名称(以便您知道何时添加创建表,何时不添加):

现在,在查询中使用几个case表达式:

SELECT  CASE WHEN PrevTableName IS NULL OR Table_N <> PrevTableName 
            THEN 'CREATE TABLE '+ Table_N +' (' 
            ELSE '' 
        END + Column_N +' '+ DType +
        CASE WHEN DLength IS NULL 
            THEN '' 
            ELSE '('+ DLength +')'
        END +
        CASE WHEN NextTableName IS NULL OR Table_N <> NextTableName 
            THEN '); '
            ELSE ', ' 
        END
FROM CTE
ORDER BY Table_N, Column_N -- Don't forget this order by, it's important!
FOR XML PATH('')

使用一个通用的表表达式lag、lead、几个case-epxpressions和for-xml-path,您可以将整个表内容的create-table语句作为一个长字符串返回

首先,创建并填充示例表(请在以后的问题中保存此步骤)

然后,使用cte获取滞后和超前表名称(以便您知道何时添加创建表,何时不添加):

现在,在查询中使用几个case表达式:

SELECT  CASE WHEN PrevTableName IS NULL OR Table_N <> PrevTableName 
            THEN 'CREATE TABLE '+ Table_N +' (' 
            ELSE '' 
        END + Column_N +' '+ DType +
        CASE WHEN DLength IS NULL 
            THEN '' 
            ELSE '('+ DLength +')'
        END +
        CASE WHEN NextTableName IS NULL OR Table_N <> NextTableName 
            THEN '); '
            ELSE ', ' 
        END
FROM CTE
ORDER BY Table_N, Column_N -- Don't forget this order by, it's important!
FOR XML PATH('')

您可以尝试生成动态语句并执行该语句。这里需要为每个不同的表名对行进行编号,然后,当行号为1时,将
createtable
包含在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)); 

您可以尝试生成动态语句并执行该语句。这里需要为每个不同的表名对行进行编号,然后,当行号为1时,将
createtable
包含在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)); 


您正在复制的功能?如果是这样,为什么呢?你好,比尔,这里的整个想法是使用来自DDC_循环的元数据来具体化100个表。从上面的示例中,我们将创建两个表,即AUT_C_TABLOG和ANLARARE您是否复制了的功能?如果是这样,为什么呢?你好,比尔,这里的整个想法是使用来自DDC_循环的元数据来具体化100个表。从上面的例子中,我们将创建两个表,即AUT_C_TABLOG和ANLAThanks Zhorov!我非常喜欢这个解决方案,只是测试了一下,效果非常好。在280个表中,有15个表出现故障,我相信这与第16个表中的一列有关。正在努力。下面的错误,并将让您张贴。消息156,级别15,状态1,第1行不正确的语法附近的关键字“备份”。Msg 102,第15级,状态1,第1行“')附近语法不正确。Msg 156,15级,状态1,第1行关键字“EXIT”附近语法不正确。回答正确!当然,佐洛夫。我试着把他们两个都标上绿色记号作为正确答案,但看起来只有一个变绿了。这就是为什么我们不得不对这两个问题发表评论。我是新来的,所以如果有别的地方我可以去,请一定告诉我。@Maximus我理解。你只能接受一个答案(这是你问题的最佳解决方案),但你可以投票否决所有答案。祝你好运,我们是来帮忙的。谢谢Zhorov!我非常喜欢这个解决方案,只是测试了一下,效果非常好。在280个表中,有15个表出现故障,我相信这与第16个表中的一列有关。正在努力。下面的错误,并将让您张贴。消息156,级别15,状态1,第1行不正确的语法附近的关键字“备份”。Msg 102,第15级,状态1,第1行“')附近语法不正确。Msg 156,15级,状态1,第1行关键字“EXIT”附近语法不正确。回答正确!当然,佐洛夫。我试着把他们两个都标上绿色记号作为正确答案,但看起来只有一个变绿了。这就是为什么我们不得不对这两个问题发表评论。我是新来的,所以如果有别的地方我可以去,请一定告诉我。@Maximus我理解。你只能接受一个答案(这是你问题的最佳解决方案),但你可以投票否决所有答案。祝你好运,我们是来帮忙的。非常感谢,佐哈尔!这也是一个很酷的解决方案!我将把它读入单独的CREATE语句中。这两个解决方案都很好。当然,我会添加创建和插入嵌套时间的脚本!呈现到XML路径的输出从第一个表的第11列开始,没有CREATE语句,但随后的表(所有279个)都非常完美。仅供参考。。输出前几个列:addrnumbervarchar(10)、CLIENT VARCHAR(3)、consnumbervarchar(3)、CREATE TABLE AXT(DATE\u FROM DATE、DFT\u RECEIV VARCHAR(1)回答正确!非常感谢,Zohar!这也是一个很酷的解决方案!我将把它读入各个CREATE语句中。这两个解决方案都很简洁。当然,我将在下一次添加CREATE和INSERT脚本!呈现到XML路径的输出从第一个表的第11列开始,没有CREATE语句,但随后所有279个表都很完美。仅供参考。输出前几列:ADDRNUMBER VARCHAR(10)、CLIENT VARCHAR(3)、conNumber VARCHAR(3)、CREATE TABLE AXT(DATE_FROM DATE、DFT_RECEIV VARCHAR(1)……回答正确!
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));