如何在 sql 服务器的存储过程中为单个参数传递更多值
how to pass more values for a single parameter in storedprocedure in sql server
我的文本:-
CREATE proc usp_delete
@tranid int
as
begin
delete from customer where tranid in(@tranid)
end
注意:- 我想通过此存储过程删除超过 1 条记录的记录,例如:- 如果我通过 1、2、3、4、5、6,那么所有 6 条记录都应该被删除
您可以使用 table-valued parameter
因为您需要声明
CREATE TYPE EntityId AS TABLE
( Id INT )
GO
CREATE PROCEDURE usp_delete
@tranid EntityId READONLY
AS
BEGIN
DELETE c
FROM customer c
JOIN @tranid t ON t.Id=c.tranid
END
为了使用 TVP 执行,声明一个类型的变量并将其传递给存储过程
DECLARE @entityId EntityId
INSERT INTO @entityId
VALUES(1),(2),(3),(4),(5)
EXEC usp_delete @entityId
在更高版本的 SQL 服务器中,您可以使用 STRING_SPLIT 将分隔列表转换为单独的值,然后使用 CROSS APPLY 加入您的 table。
CREATE PROC usp_delete @tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
CROSS APPLY STRING_SPLIT(@tranid, ',')
WHERE c.tranid = value
END
GO
EXEC usp_delete '2,3,4'
在旧版本中,您可以编写自己的 table 值函数来将定界字符串转换为结果集。
CREATE function [dbo].[delimited_string_to_table] (
@delimiter char(1)
, @string text
)
returns @table table (
seqnbr int not null
, string varchar(255) not null
)
as
begin
declare @pos int
declare @textpos int
declare @chunklen smallint
declare @tmpstr varchar(8000)
declare @leftover varchar(8000)
declare @tmpval varchar(8000)
declare @seq int = 1
set @textpos = 1
set @leftover = ''
while @textpos <= datalength(@string)
begin
set @chunklen = 8000 - datalength(@leftover) / 2
set @tmpstr = @leftover + substring(@string, @textpos, @chunklen)
set @textpos = @textpos + @chunklen
set @pos = charindex(@delimiter, @tmpstr)
while @pos > 0
begin
set @tmpval = ltrim(rtrim(left(@tmpstr, @pos - 1)))
insert @table (seqnbr, string) values(@seq, @tmpval)
set @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr))
set @pos = charindex(@delimiter, @tmpstr)
set @seq = @seq + 1
end
set @leftover = @tmpstr
end
if len(rtrim(ltrim(@leftover))) != 0
insert @table(seqnbr, string) values (@seq, ltrim(rtrim(@leftover)))
return
end
GO
这会将示例更改为如下所示:
CREATE PROC usp_delete @tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
JOIN dbo.delimited_string_to_table(',', @tranid)
ON c.tranid = string
END
GO
我的文本:-
CREATE proc usp_delete
@tranid int
as
begin
delete from customer where tranid in(@tranid)
end
注意:- 我想通过此存储过程删除超过 1 条记录的记录,例如:- 如果我通过 1、2、3、4、5、6,那么所有 6 条记录都应该被删除
您可以使用 table-valued parameter
因为您需要声明
CREATE TYPE EntityId AS TABLE
( Id INT )
GO
CREATE PROCEDURE usp_delete
@tranid EntityId READONLY
AS
BEGIN
DELETE c
FROM customer c
JOIN @tranid t ON t.Id=c.tranid
END
为了使用 TVP 执行,声明一个类型的变量并将其传递给存储过程
DECLARE @entityId EntityId
INSERT INTO @entityId
VALUES(1),(2),(3),(4),(5)
EXEC usp_delete @entityId
在更高版本的 SQL 服务器中,您可以使用 STRING_SPLIT 将分隔列表转换为单独的值,然后使用 CROSS APPLY 加入您的 table。
CREATE PROC usp_delete @tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
CROSS APPLY STRING_SPLIT(@tranid, ',')
WHERE c.tranid = value
END
GO
EXEC usp_delete '2,3,4'
在旧版本中,您可以编写自己的 table 值函数来将定界字符串转换为结果集。
CREATE function [dbo].[delimited_string_to_table] (
@delimiter char(1)
, @string text
)
returns @table table (
seqnbr int not null
, string varchar(255) not null
)
as
begin
declare @pos int
declare @textpos int
declare @chunklen smallint
declare @tmpstr varchar(8000)
declare @leftover varchar(8000)
declare @tmpval varchar(8000)
declare @seq int = 1
set @textpos = 1
set @leftover = ''
while @textpos <= datalength(@string)
begin
set @chunklen = 8000 - datalength(@leftover) / 2
set @tmpstr = @leftover + substring(@string, @textpos, @chunklen)
set @textpos = @textpos + @chunklen
set @pos = charindex(@delimiter, @tmpstr)
while @pos > 0
begin
set @tmpval = ltrim(rtrim(left(@tmpstr, @pos - 1)))
insert @table (seqnbr, string) values(@seq, @tmpval)
set @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr))
set @pos = charindex(@delimiter, @tmpstr)
set @seq = @seq + 1
end
set @leftover = @tmpstr
end
if len(rtrim(ltrim(@leftover))) != 0
insert @table(seqnbr, string) values (@seq, ltrim(rtrim(@leftover)))
return
end
GO
这会将示例更改为如下所示:
CREATE PROC usp_delete @tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
JOIN dbo.delimited_string_to_table(',', @tranid)
ON c.tranid = string
END
GO