[英]Stored procedure with variable number of parameters
我有存储过程,我必须传递参数,但问题是我不确定要传入多少个参数,它可以是 1,下次运行它可以是 5。
cmd.Parameters.Add(new SqlParameter("@id", id)
谁能帮助我如何在存储过程中传递这些可变数量的参数? 谢谢
您可以将它作为逗号分隔的列表传入,然后使用拆分函数,并根据结果进行连接。
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()
:
存储过程支持可选参数。 与 C# 4 一样,您可以使用=
指定默认值。 例如:
create procedure dbo.doStuff(
@stuffId int = null,
@stuffSubId int = null,
...)
as
...
对于不想传递的参数,要么将它们设置为null
,要么根本不将它们添加到cmd.Parameters
中。 它们将在存储过程中使用默认值
SQLServer 允许您将TABLE
参数传递给存储过程。 所以你可以定义表类型, CREATE TYPE LIST_OF_IDS AS TABLE (id int not null primary key)
,改变你的过程以接受这种类型的变量(它应该是只读的)。
您是否考虑过为此目的使用字典? 它将允许您将任意数量的参数作为键值对传递。 然后你只需要浏览字典并将这些参数添加到 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
这是一个基于,
作为分隔符分割字符串的代码片段。 您甚至可以参数化逗号。 它在还没有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
您可以执行此操作的另一种方法是将 arguments 序列化为 JSON 字符串并将其传递到您的存储过程中。 您可以使用 NewtonSoft.JSON package 执行以下操作: string json = JsonConvert.SerializeObject(obj);
并将json
var 传递到您的过程中。
如果您有 Sql Server 2008 或更高版本,则可以使用表值参数...
https://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.