我有存储过程,我必须传递参数,但问题是我不确定有多少参数可以是1,在下次运行时它可以是5.
cmd.Parameters.Add(new SqlParameter("@id", id)
任何人都可以帮助我如何在存储过程中传递这些可变数量的参数? 感谢
答案 0 :(得分:19)
您可以将其作为以逗号分隔的列表传递,然后使用拆分功能,并根据结果加入。
CREATE FUNCTION dbo.SplitInts
(
@List VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT Item = CONVERT(INT, Item)
FROM
(
SELECT Item = x.i.value('(./text())[1]', 'INT')
FROM
(
SELECT [XML] = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a
CROSS APPLY
[XML].nodes('i') AS x(i)
) AS y
WHERE Item IS NOT NULL
);
现在您的存储过程:
CREATE PROCEDURE dbo.doStuff
@List VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT cols FROM dbo.table AS t
INNER JOIN dbo.SplitInts(@List, ',') AS list
ON t.ID = list.Item;
END
GO
然后调用它:
EXEC dbo.doStuff @List = '1, 2, 3, ...';
您可以在此处查看一些背景,其他选项和效果比较:
在SQL Server 2016或更高版本上,您应该查看STRING_SPLIT()
和STRING_AGG()
:
答案 1 :(得分:6)
存储过程支持可选参数。与C#4一样,您可以使用=
指定默认值。例如:
create procedure dbo.doStuff(
@stuffId int = null,
@stuffSubId int = null,
...)
as
...
对于您不想传递的参数,请将它们设置为null
,或者根本不将它们添加到cmd.Parameters
。它们将在存储过程中具有默认值
答案 2 :(得分:5)
SQLServer允许您将TABLE
参数传递给存储过程。因此,您可以定义表类型CREATE TYPE LIST_OF_IDS AS TABLE (id int not null primary key)
,更改您的过程以接受此类型的变量(它应该只读)。
答案 3 :(得分:2)
您是否考虑过将dictionary用于此目的? 它允许您将任意数量的参数作为键值对传递。 然后你只需要浏览字典并将这些参数添加到cmd。
void DoStuff(Dictionary<string, object> parameters)
{
// some code
foreach(var param in parameters)
{
cmd.Parameters.Add(new SqlParameter(param.Key, param.Value);
}
// some code
}
在存储过程本身中,您需要指定参数的默认值。
CREATE PROCEDURE DoStuff(
@id INT = NULL,
@value INT = NULL,
-- the list of parameters with their default values goes here
)
AS
-- procedure body
答案 4 :(得分:0)
这是一个代码段,它将基于,
的字符串拆分为分隔符。您甚至可以参数化逗号。它在没有String_split
功能的系统上很有用:
DECLARE @startindex INT
DECLARE @commaindex INT
DECLARE @paramAsString VARCHAR(MAX) -- this represents the input param
DECLARE @param VARCHAR (1024)
DECLARE @paramsTable TABLE(param VARCHAR(1024) NOT NULL) -- the splitted params come here
SET @startindex = 1
WHILE @startindex < LEN(@paramAsString)
BEGIN
SET @commaindex = CHARINDEX(',', @paramAsString, @startindex)
IF @commaindex = 0
BEGIN
SET @param = SUBSTRING(@paramAsString, @startindex, LEN(@paramAsString))
SET @startindex = LEN(@settlementEntities)
END
ELSE
BEGIN
SET @param = SUBSTRING(@paramAsString, @startindex, (@commaindex - @startindex))
SET @startindex = @commaindex + 1
END
IF @se IS NOT NULL AND 0 < LEN(RTRIM(LTRIM(@param)))
BEGIN
SET @param = RTRIM(LTRIM(@param))
INSERT INTO @paramsTable (param) VALUES (@param)
END
END
答案 5 :(得分:-1)
如果您具有Sql Server 2008或更高版本,则可以使用表值参数...
https://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/