【问题标题】:Dynamic Table Insert TSQL动态表插入 TSQL
【发布时间】:2011-09-13 11:54:21
【问题描述】:

大家好,我已经为此苦苦挣扎了一段时间!我有一些带有日期的数据文件,这些文件被转储到临时表中。我希望我的脚本/函数执行的是读取暂存表中每条记录的日期并移动到适当的表。现在我知道我可以很容易地做到这一点,只需使用一些静态插入,例如

INSERT INTO TABLE_2011_08
WHERE Datafields = 2011_08

但是我希望它是动态的,所以我正在考虑按照函数/存储过程的方式传递每条记录的日期。但是我的大脑被这个融化了一点!

暂存表中的数据记录可能是这样的:-

RecordA 2011-08-30 Data Data Data
RecordB 2011-08-31 Data Data Data
RecordC 2011-09-01 Data Data Data
RecordD 2011-09-02 Data Data Data

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008 ssis


    【解决方案1】:

    给你:

    CREATE TABLE dbo.Some_Meaningful_Descriptive_Name (
        record_id    CHAR(7)        NOT NULL,
        some_date    DATETIME       NOT NULL,
        some_data    VARCHAR(20)    NOT NULL,
        ...
    )
    

    现在您的导入过程只需将它们放在表中即可。无动态需求,无需每月新建表。

    如果您真的需要让它们看起来分开,然后在表格上创建视图:

    CREATE VIEW dbo.Some_Meaningful_Descriptive_Name_2011_08
    AS
    BEGIN
    
        SELECT
            record_id,
            some_data
        FROM
            dbo.Some_Meaningful_Descriptive_Name
        WHERE
            some_date >= '2011-08-01 00:00:00.000' AND
            some_date <  '2011-09-01 00:00:00.000'
    END
    

    当您有这么多行以至于您需要将它们实际放入单独的表中时,这将是非常罕见的。 (我们说的是 10 的数百万行)。现在有了分区,即使那样也可能没有必要。

    将它们放在单独的表中只会使将来使用它们变得更加困难。

    【讨论】:

    • 是的,修复糟糕的设计。 +1,000,000
    【解决方案2】:

    如果我没听错的话,你想用动态变化的表名生成INSERT 语句吗?

    您可以将 SQL 查询构造为字符串并使用EXEC 执行它:

    DECLARE @sql nvarchar(MAX)
    SELECT @sql = N'INSERT ' + @tableName + ' VALUES (...)'
    
    EXEC (@sql)
    

    实现数据路由的最简单方法是使用游标迭代暂存数据并在该循环中创建动态插入 sql 字符串。

    然后使用单个EXEC 命令执行插入批处理。

    【讨论】:

    • 是的,这就是我想要做的。但是,它需要读取每条记录的日期字段。在暂存表中可能有 2011-08 和 2011-09 的数据,但我希望将适当的数据放到适当的表中。因此,只有 2011-08 年的数据进入 2011-08 表,只有 2011-09 年的数据进入 2011-09 表。
    • 我已经编辑了我的答案:用光标在临时表上进行迭代,并为每个数据行创建一个 INSERT
    【解决方案3】:

    表 T 与您的表相似,我用与您接近的测试数据填充它,如果您填充的表不存在,将创建它们。

    尝试重新创建您的表

    CREATE TABLE T(name varchar(10), date datetime)
    
    insert t values('RecordA','2011-08-30')
    insert t values('RecordB','2011-08-31')
    insert t values('RecordC','2011-09-01')
    insert t values('RecordD','2011-09-02')
    

    如果需要,此语法将创建和填充像 TABLE_YYYY_MM 这样的表。 YYYY和MM是任意组合发现它表T

    Declare @tablename varchar(64)
    Declare @sql as varchar(max)
    Declare @d as datetime
    Declare dCursor CURSOR FAST_FORWARD FOR
    SELECT DISTINCT dateadd(month, datediff(m, 0, date), 0) date from t
    OPEN dCursor
    FETCH NEXT FROM dCursor
    INTO @d
    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @tablename = '[TABLE_'+replace(CONVERT(VARCHAR(7), @d, 121), '-', '_') + ']'
    SET @SQL = 
    'if OBJECT_ID('''+@tablename+''', ''U'') is null 
    BEGIN
    Declare @sql2 varchar(max)
    SET @sql2 = ''SELECT * INTO '+@tablename+'
    FROM t WHERE 1 = 2''
    EXEC(@sql2)
    END
    INSERT INTO '+ @tablename+'
    SELECT * FROM t
    WHERE datediff(m, 0, date)=' + CAST(datediff(m, 0, @d) AS VARCHAR(10))
    
    EXEC(@SQL)
    FETCH NEXT FROM dCursor
    INTO @d
    
    END
    CLOSE dCursor
    DEALLOCATE dCursor
    

    【讨论】:

    • 谢谢,这正是我所追求的 :)
    猜你喜欢
    • 2010-10-17
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2015-12-21
    相关资源
    最近更新 更多