【问题标题】:How to generate columns dynamically?如何动态生成列?
【发布时间】:2012-05-03 02:56:46
【问题描述】:

我的表格有一定数量的列。

我想用 Table1 的特定列的数据动态填充其他表作为 table2 的列。

当我说动态时,我的意思是说,当任何数据添加到 Table1 的列时,table2 会填充尽可能多的列。 p>

【问题讨论】:

  • 请重新处理您的问题,因为不清楚您实际上要做什么。它与 ASP.NET 有什么关系?
  • 你是说添加到Table1的新数据应该添加到Table2,还是当向Table1添加新列时,应该自动将同一列添加到Table2? (列是元数据,而不是数据,只是为了帮助澄清。)
  • 让我澄清一下:假设我们有 2 个表 Table1 和 Table2。 Table1 有一列说“描述”。现在用户向它添加 3 行,说 A、B、C。现在我希望我应该编写一个存储过程,它将采用这 3 个值并将这些值作为列添加到 table2,以便 Table2 将 A、B、C 作为列。这应该是动态完成的,这样当用户将任何数据添加到 Table1 的描述列时,该数据将表示为 table2 中的列。
  • 您是真的想创建一个以列名作为列名的表,还是只想将数据转为输出?
  • 这比我原先想象的还要糟糕。任何能让你达到这个目标的解决方案(意味着这个特定的实现,而不是解决它背后的实际问题)都应该带有隐含的保证,即它包含潜在的多层次灾难。请阅读这篇博文,更重要的是掌握其背后的概念并阅读 cmets。 erinstellato.com/2012/05/varchar-max-index你是那个试图骑牛上班的人。告诉我们您的实际目标是什么或您要解决什么问题,而不是告诉我们您想如何解决它。

标签: asp.net sql-server-2008


【解决方案1】:

出于多种原因,动态更改架构确实不是一个好主意。根据您的描述,我认为您最好为此使用视图。视图将为您提供您正在寻找的动态功能,并且副作用更少。

请看这篇文章: How to create a view in SQL Server

【讨论】:

    【解决方案2】:

    我将再次声明这是一个坏主意,很多事情都可能出错,而且我确信对于您试图解决的任何潜在问题都有更好的解决方案。也就是说,无论如何要回答明确的问题,这里有一个如何做到这一点的示例:

    USE tempdb;
    GO
    CREATE TABLE dbo.Table1(Description VARCHAR(32));
    
    CREATE TABLE dbo.Table2(ID INT);
    
    GO
    CREATE TRIGGER dbo.CatchNewTable1Data
    ON dbo.Table1
    FOR INSERT
    AS
    BEGIN
        SET NOCOUNT ON;
    
        DECLARE @sql NVARCHAR(MAX) = N'';
    
        SELECT @sql += CHAR(13) + CHAR(10) +
            'ALTER TABLE dbo.Table2 ADD '
            + QUOTENAME(d) + ' VARCHAR(255);' -- guessing on destination data type
        FROM
        (
            SELECT DISTINCT d = LEFT([Description], 128) -- identifier <= 128
            FROM inserted AS i
            WHERE NOT EXISTS
            (
              SELECT 1 FROM sys.columns 
               WHERE name = LEFT(i.[Description], 128)
               AND [object_id] = OBJECT_ID('dbo.Table2')
            )
        ) AS x;
    
        EXEC sp_executesql @sql;
    END
    GO
    

    现在,让我们试试吧!尝试一个已经存在的列,一个已经存在一个列的多行插入,一个带有欺骗的多行插入,等等。我没有发布大于 255 的值,也没有处理任何会导致问题。为什么?因为最终我不想让你使用这个解决方案,我想解决真正的问题。但对于谷歌人来说,我想表明存在解决上述问题的方法。

    -- does nothing:
    INSERT dbo.Table1 SELECT 'ID';
    
    -- only adds column 'foo':
    INSERT dbo.Table1 SELECT 'ID'
    UNION ALL SELECT 'foo';
    
    -- adds both of these columns:
    INSERT dbo.Table1 SELECT 'bar'
    UNION ALL SELECT 'splan foob';
    
    -- only adds one of these:
    INSERT dbo.Table1 SELECT 'blat'
    UNION ALL SELECT 'blat';
    
    SELECT * FROM dbo.Table2;
    

    结果:

    ID          foo          bar          splan foob   blat
    ----------- ------------ ------------ ------------ ------------
    

    别忘了清理:

    DROP TABLE dbo.Table1, dbo.Table2;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 2012-07-01
      • 2020-04-13
      • 2017-01-30
      • 2021-11-21
      • 2010-12-31
      相关资源
      最近更新 更多