从表列表动态创建sql表

时间:2013-05-20 10:53:40

标签: sql sql-server dynamic

我正在尝试在表格列表的基础上创建一堆表格,从另一个模式中提取其表名

示例

schA table1 schA table2 schA table3

dbo tablelist在schema schA中包含此表

所以要么我需要一些代码说明 看看dbo tablelist验证它是否存在i 如果没有从数据库中的表中选择表结构到schB(这不存在)

我的问题是循环

我不是要求有人完全编写这段代码(尽管会有所帮助:-) 但如何构建我的查询或最佳启动方式

提前非常感谢

1 个答案:

答案 0 :(得分:0)

这可能对你有所帮助 -

<强> DDL:

CREATE TABLE [dbo].[test1](
    [company_id] [int] NOT NULL PRIMARY KEY,
    [staff_name] [nvarchar](50) NULL,
    [email] [nvarchar](50) NULL
) ON [PRIMARY]

<强>查询:

DECLARE 
      @table_name SYSNAME
    , @name_for_new_table SYSNAME
    , @schema_for_new_table SYSNAME

SELECT 
      @table_name = 'dbo.test1'
    , @schema_for_new_table = 'dbo' 
    , @name_for_new_table = 'test1_new'

DECLARE @SQL NVARCHAR(MAX) = ''

;WITH tbl AS 
(
    SELECT o.[object_id]
    FROM sys.objects o WITH (NOWAIT)
    WHERE SCHEMA_NAME(o.[schema_id]) + '.' + o.name = @table_name
        AND o.[type] = 'U'
        AND o.is_ms_shipped = 0
),
index_column AS 
(
    SELECT 
          ic.[object_id]
        , ic.index_id
        , ic.is_descending_key
        , ic.is_included_column
        , c.name
    FROM sys.index_columns ic WITH (NOWAIT)
    JOIN sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
    WHERE ic.[object_id] IN (SELECT t.[object_id] FROM tbl t)
),
fk_columns AS 
(
     SELECT 
          k.constraint_object_id
        , cname = c.name
        , rcname = rc.name
    FROM sys.foreign_key_columns k WITH (NOWAIT)
    JOIN sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id 
    JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
)
SELECT @SQL = 'CREATE TABLE [' + @schema_for_new_table + '].[' + @name_for_new_table + ']' + CHAR(13) + '(' + CHAR(13) + STUFF((
    SELECT DISTINCT CHAR(9) + ', [' + c.name + '] ' + UPPER(t.name) + 
        CASE WHEN t.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
               THEN '(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length AS NVARCHAR(5)) END + ')'
             WHEN t.name IN ('nvarchar', 'nchar', 'ntext')
               THEN '(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length / 2 AS NVARCHAR(5)) END + ')'
             WHEN t.name IN ('datetime2', 'time2', 'datetimeoffset') 
               THEN '(' + CAST(c.scale AS NVARCHAR(5)) + ')'
             WHEN t.name = 'decimal' 
               THEN '(' + CAST(c.[precision] AS NVARCHAR(5)) + ',' + CAST(c.scale AS NVARCHAR(5)) + ')'
            ELSE ''
        END +
        CASE WHEN c.collation_name IS NOT NULL THEN ' COLLATE ' + c.collation_name ELSE '' END +
        CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END +
        CASE WHEN c.[definition] IS NOT NULL THEN ' DEFAULT' + c.[definition] ELSE '' END + 
        CASE WHEN c.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(c.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(c.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END + CHAR(13)
    FROM (
        SELECT 
              c.name
            , c.user_type_id
            , c.max_length
            , c.[precision]
            , c.scale
            , dc.[definition]
            , ic.seed_value
            , ic.increment_value
            , c.collation_name
            , c.is_nullable
            , c.is_identity 
        FROM sys.columns c WITH (NOWAIT)
        LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id
        LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
        WHERE c.[object_id] IN (SELECT o.[object_id] FROM tbl o)
    ) c
    JOIN sys.types t WITH (NOWAIT) ON c.user_type_id = t.user_type_id
    FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
    + ISNULL((SELECT CHAR(9) + ', CONSTRAINT [PK_' + @schema_for_new_table + '_' + @name_for_new_table + '] PRIMARY KEY (' + 
            (SELECT STUFF((
             SELECT DISTINCT ', [' + c.name + ']' + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
             FROM sys.key_constraints k WITH (NOWAIT) 
             JOIN sys.index_columns ic WITH (NOWAIT) ON ic.[object_id] = k.parent_object_id AND ic.index_id = k.unique_index_id
             JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = ic.column_id
             WHERE k.[type] = 'PK'
                 AND ic.is_included_column = 0
                 AND k.parent_object_id IN (SELECT t.[object_id] FROM tbl t)
             FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')) + ')'  + CHAR(13)), '')
    + ')' + CHAR(13)
    + ISNULL((SELECT (
        SELECT CHAR(13) +
             'ALTER TABLE [' + @schema_for_new_table + '].[' + @name_for_new_table + '] WITH' 
            + CASE WHEN fk.is_not_trusted = 1 
                THEN ' NOCHECK' 
                ELSE ' CHECK' 
              END + 
              ' ADD CONSTRAINT [FK_' + @schema_for_new_table + '_' + @name_for_new_table + '_' + fk.name  + '] FOREIGN KEY(' 
              + STUFF((
                SELECT ', [' + k.cname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')' +
              ' REFERENCES [' + SCHEMA_NAME(ro.[schema_id]) + '].[' + ro.name + '] ('
              + STUFF((
                SELECT ', [' + k.rcname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')'
            + CASE 
                WHEN fk.delete_referential_action = 1 THEN ' ON DELETE CASCADE' 
                WHEN fk.delete_referential_action = 2 THEN ' ON DELETE SET NULL'
                WHEN fk.delete_referential_action = 3 THEN ' ON DELETE SET DEFAULT' 
                ELSE '' 
              END
            + CASE 
                WHEN fk.update_referential_action = 1 THEN ' ON UPDATE CASCADE'
                WHEN fk.update_referential_action = 2 THEN ' ON UPDATE SET NULL'
                WHEN fk.update_referential_action = 3 THEN ' ON UPDATE SET DEFAULT'  
                ELSE '' 
              END 
            + CHAR(13) + 'ALTER TABLE [' + @schema_for_new_table + '].[' + @name_for_new_table + '] CHECK CONSTRAINT [FK_' + @schema_for_new_table + '_' + @name_for_new_table + '_' + fk.name  + ']' + CHAR(13)
        FROM sys.foreign_keys fk WITH (NOWAIT)
        JOIN sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
        WHERE fk.parent_object_id IN (SELECT t.[object_id] FROM tbl t)
        FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)')), '')
    + ISNULL(((SELECT
         CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END + ' NONCLUSTERED INDEX [IX_' + @schema_for_new_table + '_' + @name_for_new_table + '_' + i.name + '] ON [' + @schema_for_new_table + '].[' + @name_for_new_table + '] (' +
                STUFF((
                SELECT ', [' + c.name + ']' + CASE WHEN c.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
                FROM index_column c
                WHERE c.is_included_column = 0
                    AND c.index_id = i.index_id
                FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '') + ')'  
                + ISNULL(CHAR(13) + 'INCLUDE (' + 
                    STUFF((
                    SELECT ', [' + c.name + ']'
                    FROM index_column c
                    WHERE c.is_included_column = 1
                        AND c.index_id = i.index_id
                    FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '')  + CHAR(13)
        FROM sys.indexes i WITH (NOWAIT)
        WHERE i.[object_id] IN (SELECT t.[object_id] FROM tbl t)
            AND i.is_primary_key = 0
            AND i.[type] = 2
        FOR XML PATH(N''), TYPE, ROOT).value('root[1]', 'NVARCHAR(MAX)')
    ), '')

PRINT @SQL
--EXEC sys.sp_executesql @SQL

<强>输出:

CREATE TABLE [dbo].[test1_new]
(
      [company_id] INT NOT NULL
    , [email] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    , [staff_name] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
    , CONSTRAINT [PK_dbo_test1_new] PRIMARY KEY ([company_id] ASC)
)