我创建了一个sproc来删除多个记录,方法是接受以逗号分隔的ID列表为varchar,并使用IN来尝试删除 - 不起作用:
ALTER PROCEDURE [dbo].[sp_DeleteItemsFromItemCategories]
@UserID bigint,
@ItemsList varchar(8000)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DELETE
FROM tbl_ItemFoldersLnk
WHERE LineItemID IN (SELECT LineItemID FROM tbl_ItemFoldersLnk WHERE LineItemID IN (@ItemsList))
END
最初我有... IN(@ItemList)但仍然无效。错误是“将数据类型varchar转换为bigint时出错。”
我确实有其他SPROCS迭代逗号分隔列表,我可以用它来删除,但后来我为每一行运行一个删除函数。
建议?
感谢。
答案 0 :(得分:1)
答案 1 :(得分:1)
假设字符串是以逗号分隔的整数值列表,请尝试:
SET @ ItemsList =','+ replace(@ItemsList,'','')+','
现在列表中应该包含逗号分隔的每个数字,并删除多余的空格。删除查询变为
删除 FROM tbl_ItemFoldersLnk 在哪里Charindex(','+ ltrim(str(LineItemID))+',',@ ItemList)> 0 强>
性能不会很好,但它会完成工作......
答案 2 :(得分:0)
您可以将输入字符串解析为离散值(例如,通过用户定义的函数),将这些值插入到表对象中,然后发出一个删除命令,该命令对表变量中的所有值使用IN操作。 ...
...或者您可以将XML发送到您的过程并使用FOR XML操作来执行类似操作(即将XML解析为表变量等等。
无论哪种方式,您都需要以类似于表格的数据而不是以逗号分隔的字符串结束。
答案 3 :(得分:0)
看起来像SQL Server代码。如果是这样,这是一个将分隔列表转换为表格的UDF:
Create Function [dbo].[ParseTextString] (@S Text, @delim VarChar(5))
Returns @tOut Table
(ValNum Integer Identity Primary Key,
sVal VarChar(8000))
As
Begin
Declare @dLLen TinyInt -- Length of delimiter
Declare @sWin VarChar(8000) -- Will Contain Window into text string
Declare @wLen Integer -- Length of Window
Declare @wLast TinyInt -- Boolean to indicate processing Last Window
Declare @wPos Integer -- Start Position of Window within Text String
Declare @sVal VarChar(8000) -- String Data to insert into output Table
Declare @BtchSiz Integer -- Maximum Size of Window
Set @BtchSiz = 7900 -- (Reset to smaller values to test routine)
Declare @dPos Integer -- Position within Window of next Delimiter
Declare @Strt Integer -- Start Position of each data value within Window
-- -------------------------------------------------------------------------
-- Default delimiter is pipe char -----
If @delim is Null Set @delim = '|'
If DataLength(@S) = 0 Or
Substring(@S, 1, @BtchSiz) = @delim Return
-- ---------------------------
Select @dLLen = Len(@delim),
@Strt = 1, @wPos = 1,
@sWin = Substring(@S, 1, @BtchSiz)
Select @wLen = Len(@sWin),
@wLast = Case When Len(@sWin) = @BtchSiz
Then 0 Else 1 End,
@dPos = CharIndex(@delim, @sWin, @Strt)
-- ----------------------------
While @Strt <= @wLen
Begin
If @dPos = 0 -- No More delimiters in window
Begin
If @wLast = 1 Set @dPos = @wLen + 1
Begin
Set @wPos = @wPos + @Strt - 1
Set @sWin = Substring(@S, @wPos, @BtchSiz)
-- ----------------------------------------
Select @wLen = Len(@sWin), @Strt = 1,
@wLast = Case When Len(@sWin) = @BtchSiz
Then 0 Else 1 End,
@dPos = CharIndex(@delim, @sWin, 1)
If @dPos = 0 Set @dPos = @wLen + 1
End
End
-- -------------------------------
Set @sVal = LTrim(Substring(@sWin, @Strt, @dPos - @Strt))
Insert @tOut (sVal) Values (@sVal)
-- -------------------------------
-- Move @Strt to char after last delimiter
Set @Strt = @dPos + @dLLen
Set @dPos = CharIndex(@delim, @sWin, @Strt)
End
Return
End
答案 4 :(得分:0)
我通常会将CSV转换为表格。但是,另一种简单的方法是构建一个字符串和exec或sp_executesql字符串。这有一些安全隐患。您可能需要以不同方式管理权限,因为调用者需要具有执行存储过程的权限以及从表中删除的权限。
DECLARE @sql varchar(max)
SELECT @sql ='DELETE FROM tbl_ItemFoldersLnk WHERE LineItemID IN('+ @sql +')'
EXEC(@sql)