【问题标题】:How to dynamically generate table column definitions in SQL Server 2008 function如何在 SQL Server 2008 函数中动态生成表列定义
【发布时间】:2009-05-13 20:46:29
【问题描述】:

在SQL Server 2008我有一种情况,需要返回一个动态生成的表,列也是动态生成的。

这一切都是由查询生成的,因为我从一个 id 开始,然后我得到列名和类型,这就是强制转换的原因。

以下是最终查询,在一种情况下将返回我想要的表,但此类似查询可用于返回多个表。

这目前在 C# 中实现,但我希望它在存储过程或函数中是可行的,但是,我不确定如何进行多个查询来构建此查询,然后返回表。

谢谢。

SELECT ResultID, ResultName, ResultDescription, 
CAST([233] AS Real) as [ResultColA], 
CAST([234] AS Int) as [ResultColB], 
CAST([236] AS NVarChar) as [ResultColC], 
CAST([237] AS Int) as [ResultColD]
FROM (
    SELECT st.*, avt.ResultID as avtID, avt.SomeAttrID, avt.Value 
    FROM Result_AV avt 
    JOIN Result st ON avt.ResultID = st.ResultID) as p 
    PIVOT ( 
        MAX(Value) FOR AttributeID IN ([233], [234], [236], [237])) as pvt

更新:如果我有一张包含汽车制造商的表格,并且我想要通用汽车制造的汽车的所有属性。我会查找汽车的信息,用它来获取所有汽车制造商,这将是通用汽车,然后我想获取通用汽车制造的所有汽车的信息,但是,由于信息是动态生成的列是不同的。 那就是我所在的地方,需要动态生成这个表。我很好奇我是否可以调用 Web 服务,获取动态生成的查询,然后让存储过程或函数执行该查询。

更新 2:获得此表后的下一步是,我需要将汽车上的所有选项(在本例中)相加,以确定汽车的实际价格。这就是为什么它需要采用表格格式。此时,我正在查看 GM 制造的汽车,但我可以对 SeaRay 制造的船只进行另一个查询,即使船上的表列与汽车不同,查询也应该可以正常工作。

【问题讨论】:

  • 我质疑您是否需要返回动态生成的表格。你能提供一些背景说明为什么这是必要的吗?
  • 我有一个表格,列出了数据库中的所有表格。所以,我从一个实体名称开始,我用它来获取表中的列名以及主键。然后,在这个阶段,我想获取该实体的每一列中的所有值,因此列名是动态生成的。

标签: tsql sql-server-2008 stored-procedures dynamic-sql


【解决方案1】:

您可以使用动态 SQL 来做到这一点。您需要使用查询和/或元数据适当地构建两个列表,然后将它们插入 SQL:

DECLARE @template AS varchar(MAX)

SET @template = '
SELECT ResultID, ResultName, ResultDescription
{@SELECT_COLUMN_LIST}
FROM (
    SELECT st.*, avt.ResultID as avtID, avt.SomeAttrID, avt.Value 
    FROM Result_AV avt 
    JOIN Result st ON avt.ResultID = st.ResultID) as p 
    PIVOT ( 
        MAX(Value) FOR AttributeID IN ({@PIVOT_COLUMN_LIST})) as pvt'

DECLARE @sql AS varchar(MAX)

SET @sql = REPLACE(REPLACE(@template, '{@SELECT_COLUMN_LIST}', @SELECT_COLUMN_LIST), '{@PIVOT_COLUMN_LIST}', @PIVOT_COLUMN_LIST)

EXEC (@sql)

要填充@SELECT_COLUMN_LIST@PIVOT_COLUMN_LIST,您有多种选择,但这样的操作避免了对光标或笨拙的字符串操作的任何需求:

SELECT @PIVOT_COLUMN_LIST = COALESCE(@PIVOT_COLUMN_LIST, '') + ',' + QUOTENAME(value)
FROM (SELECT DISTINCT value FROM table)

显然对于@SELECT_COLUMN_LIST,您需要将此信息与一些元数据结合起来。

为了便于维护,我做了类似的事情,因为 PIVOT 和 UNPIVOT 不允许列表是动态 SQL(因为它们会导致输出表上的架构更改)。对于不解释列的客户端报告样式或列表框使用,这无关紧要。

【讨论】:

  • 非常感谢。我正在努力理解如何使用这样一个动态数据库。 :)
  • 一般来说,尝试在数据库中构建数据库是个坏主意,但动态 SQL 有它的位置 - 通常是任何系统的很小一部分,如果有的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
相关资源
最近更新 更多