我有一个简单的存储过程,如下所示:
[dbo].[getStatusList]
@Extended NVARCHAR(255) = 'Project Status',
@Exclude NVARCHAR(255) = '',
@All BIT = 0
AS
SET NOCOUNT ON
IF (@All = 0)
BEGIN
SELECT
[GeneralKey],
[Label]
FROM
[General]
WHERE
[Extended] = @Extended
AND [Label] <> @Exclude
ORDER BY
[OrderID];
END
ELSE
BEGIN
IF (@All = 1)
BEGIN
SELECT
0 AS [GeneralKey],
'Any' AS [Label],
0 AS [OrderID]
UNION ALL
SELECT
[GeneralKey],
[Label],
[OrderID]
FROM
[General]
WHERE
[Extended] = @Extended
AND [Label] <> @Exclude
ORDER BY
[OrderID];
END
END
我想做的是执行此存储过程,发送两次@Extended
参数,例如:
exec getStatusList @Extended = 'title1' AND @Extended = 'title2'
不可能在exec
上做类似的事情吗?解决此问题的唯一方法是在存储过程中添加另一个参数?
更新
正如下面提到的评论,我尝试过:
CREATE OR ALTER PROCEDURE usp_Get_StatusListByDesignType
-- Add the parameters for the stored procedure here
@Extended NVARCHAR(MAX),
@Exclude NVARCHAR(255) = '',
@All BIT = 0
AS
SET NOCOUNT ON
IF (@All = 0)
BEGIN
DECLARE @Parameter1 VARCHAR(50)
DECLARE @Parameter2 VARCHAR(50)
;WITH CTE AS
(
SELECT
*,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) rn
FROM
STRING_SPLIT (@Extended,',')
)
SELECT
@Parameter1 = MAX(CASE WHEN rn = 1 THEN VALUE END),
@Parameter2 = MAX(CASE WHEN rn = 2 THEN VALUE END)
FROM
CTE
SELECT
[GeneralKey], [Label]
FROM
[General]
WHERE
[Extended] IN (SELECT @Parameter1, @Parameter2)
AND [Label] <> @Exclude
ORDER BY
[OrderID];
END
ELSE
BEGIN
IF (@All = 1)
BEGIN
SELECT
0 AS [GeneralKey],
'Any' AS [Label],
0 AS [OrderID]
UNION ALL
SELECT
[GeneralKey],
[Label],
[OrderID]
FROM
[General]
WHERE
[Extended] IN (SELECT @Parameter1, @Parameter2)
AND [Label] <> @Exclude
ORDER BY
[OrderID];
END
RETURN;
但是我得到这个错误:
当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式。
答案 0 :(得分:2)
您可以传递与para1Val1,para1Val2...
逗号连接的,
之类的参数。
然后使用STRING_SPLIT
函数将其与,
逗号分开,然后获取参数。
DECLARE @Extended varchar(max)='title1,titl2'
这很简单
DECLARE @Extended varchar(max)='title1,titl2'
select *,row_number() over(order by (select NULL)) rn
from STRING_SPLIT (@Extended,',')
然后您可以在SP
中设置参数。
声明参数变量,然后使用row_number设置参数行号。
下一步使用条件聚合函数在select
子句中设置参数。
declare @parameter1 varchar(50)
declare @parameter2 varchar(50)
;with cte as (
select *,row_number() over(order by (select NULL)) rn
from STRING_SPLIT (@Extended,',')
)
select @parameter1 = MAX(case when rn = 1 then value end),
@parameter2 = MAX(case when rn = 2 then value end)
from cte
答案 1 :(得分:0)
此方法:
exec getStatusList @Extended='title1' AND @Extended = 'title2'
它根本不起作用,因为参数或变量通常只能容纳一个值,仅此而已。因此,除非执行两次存储过程并在每个存储过程上指定参数,否则您将无法执行此操作。或者,您可以使用循环来做到这一点。但是我不喜欢循环,我总是建议尽可能避免循环。
我认为适合您情况的方法是对存储过程本身进行了一些修改的TVP。
因此,您将在@Extended
中以逗号分隔的值传递值,并从存储过程中使用IN()
和NOT IN()
而不是=
和{ {1}}会将其扩展为具有更多要比较的值,而不是一个值。
然后,您可以使用XML拆分值并将它们变成行。
所以我们将使用它:
<>
您可以通过修改我上面提到的运算符将其直接注入到存储过程中,并且可以正常工作。但为了代码重用,我们将其用作TVP。
SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)')))
FROM (
SELECT CAST('<XMLRoot><RowData>' + REPLACE(@Extended,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) Extended
) D
CROSS APPLY Extended.nodes('/XMLRoot/RowData')m(n)
现在,您可以将存储过程修改为以下内容:
CREATE FUNCTION SplitToRows
(
@Extended VARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN
(
SELECT LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) Extended
FROM (
SELECT CAST('<XMLRoot><RowData>' + REPLACE(@Extended,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) Extended
) D
CROSS APPLY Extended.nodes('/XMLRoot/RowData')m(n)
)
现在,您可以像这样同时在@Extended和@Exclude中传递多个单独的值:
[dbo].[getStatusList]
@Extended NVARCHAR(255) = 'Project Status'
, @Exclude NVARCHAR(255) = ''
, @All BIT = 0
AS
SET NOCOUNT ON
IF(@All = 0)
BEGIN
SELECT
[GeneralKey]
, [Label]
FROM [General]
WHERE
[Extended] IN( SELECT * FROM dbo.SplitToRows(@Extended) )
AND [Label] NOT IN( SELECT * FROM dbo.SplitToRows(@Exclude) )
ORDER BY
[OrderID];
END
ELSE
BEGIN
IF(@All = 1)
BEGIN
SELECT
0 AS [GeneralKey]
, 'Any' AS [Label]
, 0 AS [OrderID]
UNION ALL
SELECT
[GeneralKey]
, [Label]
, [OrderID]
FROM [General]
WHERE
[Extended] IN( SELECT * FROM dbo.SplitToRows(@Extended) )
AND [Label] NOT IN( SELECT * FROM dbo.SplitToRows(@Exclude) )
ORDER BY
[OrderID];
END
END
所以两个参数将使用相同的方法。