首页 > 解决方案 > SQL 游标而不是 select 语句的 union

问题描述

我有一个需要更新的 SQL Server 过程。目前,它有 3 个 INPUT 参数(程序 ID),并使用这些参数运行由 UNION ALL 连接的 3 个 SELECT 语句。现在要求已更改为可以将 2 或 3 个 INPUT 参数传递给它的地方。

创建另一个过程,并根据 IF 条件从我的 ASP.Net 站点调用任一过程对我来说简直是个糟糕的主意。相反,我希望能够压缩存储过程以允许可变数量的 INPUT 参数并运行相同的选择语句,而不必使用 UNION ALL。

目前它是这样的:

SELECT name, startdate, enddate FROM xyztable WHERE x1 = id1
UNION ALL
SELECT name, startdate, enddate FROM xyztable WHERE x1 = id2
UNION ALL
SELECT name, startdate, enddate FROM xyztable WHERE x1 = id3

光标会是执行此操作的理想方法吗?(对它们的工作方式有点困惑)

更新

我已经尝试了以下以及 using IN (xxx, xxx, xxx),但是,它使每条记录增加了三倍。我是否必须对代码进行重大返工?

SELECT 
    WS.ProgramID,
    WS.ItemID,
    WS.Day,
    CASE DATEPART(WEEKDAY, DATEADD(DAY, WS.Day - 1, WE.eventstartdate))
       WHEN 1 THEN 'Sun'
       WHEN 2 THEN 'Mon'
       WHEN 3 THEN 'Tue'
       WHEN 4 THEN 'Wed'
       WHEN 5 THEN 'Thu'
       WHEN 6 THEN 'Fri'
       WHEN 7 THEN 'Sat'
       ELSE 'N/A'
    END + ' '
        + CONVERT(CHAR(12), DATEADD(DAY, WS.Day - 1, WE.eventstartdate), 101) AS Date, CONVERT(VARCHAR(15), CONVERT(TIME, SUBSTRING(WS.TimeSlot, 0, 6)), 100) AS 'Begin TIME',
    CONVERT(VARCHAR(15), CONVERT(TIME, SUBSTRING(WS.TimeSlot, 7, 6)), 100) AS 'End TIME',
    WS.TimeSlot,
    WS.SlotType,
    WSSTC.Description AS SlotTypeDescription,
    WS.SlotInfo,
    WSSIC.Description AS SlotInfoDescription,
    ISNULL(WSI.TalkID, 0) AS TalkID,
    LEFT(WPI.FirstName, 10) + ' ' + LEFT(WPI.LastName, 10) + ' ('
           + LEFT(WEA.institution, 10) + ')' + ' - '
           + LEFT(WSI.Title, 10) + '...' + RIGHT(WSI.Title, 10) AS Talk,
    WPI.FirstName,
    WPI.LastName,
    WEA.institution,
    WSI.AuthorLine,
    WSI.Title,
    LEFT(WSI.Abstract, 1) AS Abstract,
    WS.Location,
    WS.Addendum,
    WE.EventName
FROM   
    dbo.WebSpeakerInfo WSI
INNER JOIN 
    dbo.WebPersonalInfo WPI ON WSI.UserID = WPI.UserID
INNER JOIN 
    dbo.webeventaffiliation WEA ON WPI.UserID = WEA.userid
                                AND (WEA.eventid = 3515 OR wea.eventid = 3516 OR WEA.eventid = 3471)
RIGHT OUTER JOIN 
    dbo.WebScheduleSlotTypeCodes WSSTC
RIGHT OUTER JOIN 
    dbo.WebSchedules WS ON WSSTC.SlotType = WS.SlotType 
    ON WSI.TalkID = WS.TalkID
LEFT OUTER JOIN 
    dbo.WebScheduleSlotInfoCodes WSSIC ON WS.SlotInfo = WSSIC.SlotInfo
INNER JOIN 
    dbo.WebEvents WE ON (WE.eventid = 3515 OR we.eventid = 3516 OR WE.eventid = 3471)
WHERE  
    (WS.ProgramID = 3515 OR ws.ProgramID = 3516 OR ws.ProgramID = 3471)
    AND WS.SlotType <> 6

标签: sqlstored-procedurescursorunion-allsql-server-2017

解决方案


您可以使用一系列相等条件,or它们之间带有 s(或一个in条件,这只是它们的简写)。由于null永远不能等于一个值,并且null您传递给第二个和第三个 id 的 s 将被忽略:

SELECT name, startdate, enddate FROM xyztable WHERE x1 IN (id1, id2, id3)

推荐阅读