【问题标题】:Dynamically Changing what table to select from with SQL CASE statement使用 SQL CASE 语句动态更改要从中选择的表
【发布时间】:2010-10-04 07:18:54
【问题描述】:

我正在尝试编写一个存储过程,并且根据某个列值,我希望能够更改我从中选择的表。我试着举个例子:

SELECT ItemNumber,
       ItemType, 
       Description
FROM

CASE ItemType
WHEN 'A' THEN TableA
ELSE TableB
END

WHERE 

CASE ItemType
WHEN 'A' THEN ItemNumber = @itemNumber
ELSE PartNumber = @itemNumber
END

如您所见,我不仅动态更改了我从中选择的表,而且由于这两个表是由两个不同的人在两个不同的时间制作的,所以列名也不同。

所以,我的问题是:最好的方法是什么,因为 SQL Server 似乎不喜欢我构建的查询。

如果有人看到我正在尝试做的事情可以提出更好的方法来做到这一点,我会全神贯注:-)

【问题讨论】:

  • 虽然人们通常假设“SQL Server”==“MS SQL Server”,但最好在问题和标签中澄清这一点。我正在更改标签,如果我错了,请恢复。
  • sqlserver 是 Microsoft SQL Server 的标记。目前没有同名的其他产品,它是 SO 上唯一有用的标签。

标签: sql sql-server dynamic-sql


【解决方案1】:

您最好先使用 UNION 查询来连接表,然后再使用 SELECT。

此外,您可以考虑为其中一个表创建一个视图,以便在重命名它们时只提取您需要的列,然后是 UNION,然后从 UNION 中进行选择。

或者使用临时表来存储每个查询的结果。将临时表的创建放在一个CASE中(伪代码,未测试):

CASE @itemType
   WHEN 'A'
      SELECT ACol1 AS Col1, ACol2 AS Col2
      FROM TABLE_A
      INTO #tempTable
      WHERE ItemNumber = @itemNumber
   ELSE
      SELECT BCol1 AS Col1, BCol2 AS Col2
      FROM TABLE_B
      INTO #tempTable
      WHERE PartNumber = @itemNumber
END

SELECT * FROM #tempTable

【讨论】:

    【解决方案2】:

    您可以尝试将动态 SQL 语句构建为字符串,然后调用 sp_executesql 存储过程来执行该字符串。

    有关更多信息和示例,请参阅here

    【讨论】:

    • 我怀疑这里是否真的需要动态 SQL,除非架构更加病态。
    • 我同意 SP 的设计确实很糟糕,但我认为这是解决所提出问题的最简单方法。
    • 我认为问题的具体说明不足以确定它不能首先使用基本 SQL 来解决。在普通 SQL 的障碍表明它是正确的选择之前,一般不应该考虑动态 SQL。
    【解决方案3】:

    你真的没有解释ItemType 的来源。正如建议的那样,UNION 可能适用,如果您只是组合两个表。

    这是另一种可能与您的问题有关的可能性:

    SELECT ItemNumber,
           ItemType, 
           COALESCE(TableA.Description, TableB.Description) AS Description
    FROM Items
    LEFT JOIN TableA
        ON Items.ItemType = 'A'
        AND TableA.ItemNumber = Items.ItemNumber
    LEFT JOIN TableB
        ON Items.ItemType <> 'A'
        AND TableB.ItemNumber = Items.ItemNumber
    

    【讨论】:

      【解决方案4】:

      您不能在 FROM 子句中使用 CASE 语句,但可以使用以下语句:

      SELECT itemnumber, itemtype, description
        FROM tablea
       WHERE itemnumber = @itemnumber AND itemtype = 'A'
      UNION ALL
      SELECT itemnumber, itemtype, description
        FROM tableb
       WHERE partnumber = @itemnumber AND itemtype <> 'A'
      

      【讨论】:

        【解决方案5】:

        我不知道你为什么要在一个 SQL 语句中做事.. 我不是 SQL Server 人,但在 Oracle 存储过程中你可以写这样的东西

        If itemtype = 'A' 
        Then 
         <statement for table A>
        Else
         <statement for Table B>
        End if
        

        类似的东西也应该在 SQL Server 中工作......也许有人可以扩展它?

        【讨论】:

        • 我也会这样做
        【解决方案6】:

        可以是动态查询,也可以采用以下方法:

        SELECT 
          CASE ItemType
            WHEN 'A' THEN (Select ItemNumber from TableA Where ItemNumber = @itemNumber)
            When 'B' THEN (Select ItemNumber from TableB Where ItemNumber = @itemNumber)
          End as ItemNumber,
          CASE ItemType
            WHEN 'A' THEN (Select ItemType from TableA Where ItemNumber = @itemNumber)
            When 'B' THEN (Select ItemType from TableB Where ItemNumber = @itemNumber)
          End as ItemType,
          CASE ItemType
            WHEN 'A' THEN (Select Description from TableA Where ItemNumber = @itemNumber)
            When 'B' THEN (Select Description from TableB Where ItemNumber = @itemNumber)
          End as Description 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-21
          相关资源
          最近更新 更多