FROM 子句取决于变量值

FROM clause depending on variable value

我有两个列名相同的表,我想根据一个参数值从一个或另一个获取数据。我想到的是

ALTER PROCEDURE [dbo].[traxs_SyncLists_Locations_Search]

    @session_id varchar(30),
    @get_value int,
    @predicate varchar(50),
    @combo varchar(30)

AS

    SELECT
        L.id AS id, 
        L.location AS value
    FROM
        CASE 
            WHEN @combo = 'box' THEN vw_WarehouseLocationBox
            WHEN @combo = 'bay' THEN vw_WarehouseLocationBay
        END L
            LEFT JOIN traxs_temp..__LocationsSyncLists T ON T.session_id = @session_id AND T.id = L.id
    WHERE
        L.whse_no = @get_value AND
        ISNULL(T.archive, 1) = 1 AND
        L.location LIKE @predicate + '%'

SQL 语法不正确。经过一番研究,我写道

SELECT 
    L.id AS id, 
    L.location AS value
FROM
    vw_WarehouseLocationBox L
        LEFT JOIN traxs_temp..__LocationsSyncLists T ON T.session_id = @session_id AND T.id = L.id
WHERE
    @combo = 'box' AND -- TRICK
    L.whse_no = @get_value AND
    ISNULL(T.archive, 1) = 1 AND
    L.location LIKE @predicate + '%'
UNION
SELECT 
    L.id AS id, 
    L.location AS value
FROM
    vw_WarehouseLocationBay L
        LEFT JOIN traxs_temp..__LocationsSyncLists T ON T.session_id = @session_id AND T.id = L.id
WHERE
    @combo = 'bay' AND -- TRICK
    L.whse_no = @get_value AND
    ISNULL(T.archive, 1) = 1 AND
    L.location LIKE @predicate + '%'

但我总是对重复一些代码感到难过。它只有 2 个表,但如果稍后(可能)有 10 个表怎么办,我应该将其复制 10 次吗?还是我应该使用动态 SQL,即使我看到很多人反对它?

您可以将可变部分和不可变部分分开。可变的将包含基本表的 UNION 和不可变的 - 其他代码。可能是复制和动态之间的折衷 SQL.

WITH L AS (
    SELECT 
        id AS id, 
        location AS value,
        whse_no,
        'box' AS combo
    FROM vw_WarehouseLocationBox
    UNION ALL
    SELECT 
        id, 
        location,
        whse_no,
        'bay'
    FROM vw_WarehouseLocationBay
)
SELECT 
    id,
    value
FROM L
LEFT JOIN traxs_temp..__LocationsSyncLists T ON T.session_id = @session_id AND T.id = L.id
WHERE
    @combo = combo AND
    L.whse_no = @get_value AND
    ISNULL(T.archive, 1) = 1 AND
    L.location LIKE @predicate + '%'

结构看起来像 typeof,其中 WarehouseLocation 是通用类型,Box、Bay 等是扩展类型。

您的查询似乎只需要一般信息。如果您有权这样做,我会在前两个视图 vw_WarehouseLocation 之上创建一个视图,并在此处使用您已经确定的联合方法维护组合逻辑,但包括一个附加字段 "whse_type"识别类型。

create view [vw_WarehouseLocation]
as

select
      [id] as [id]
    , [location] as [location]
    , [whse_no] as [whse_no]
    , 'bay' as [whse_type]
from [vw_WarehouseLocationBay]

union all

select
      [id] as [id]
    , [location] as [location]
    , [whse_no] as [whse_no]
    , 'box' as [whse_type]
from [vw_WarehouseLocationBox]

现在,您不仅可以在当前 SP 中加入此视图,而且可以在任何其他对象中加入此视图,而无需在此处复制逻辑,即使它在视图中看起来确实笨拙且重复。此方法以可支持的方式更符合 "patching up designs"。

例如,

select
      L.id
    , L.location
from vw_WarehouseLocation L
left join traxs_temp..__LocationsSyncLists T
    on T.id = L.id
where L.[whse_type] = @combo