我有一个像这样的关系映射表:
attributeid bigint
productid bigint
要清除不再使用的关系,我想删除所有recctid = x和attributeid不在(@includedIds)的recor,如下例所示:
@attributetypeid bigint,
@productid bigint,
@includedids varchar(MAX)
DELETE FROM reltable
WHERE productid = @productid AND
attributetypeid = @attributetypeid AND
attributeid NOT IN (@includedids);
当运行带有包含多于1个id的includedids param的SQL时 - 就像这样:25,26 - 我得到一个SqlException说:
将数据类型varchar转换为bigint时出错。
这当然是由于varchar(max)参数...
我应该如何构建我的删除语句以使其工作?
答案 0 :(得分:2)
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[ListToTable] (
/*
FUNCTION ListToTable
Usage: select entry from listtotable('abc,def,ghi') order by entry desc
PURPOSE: Takes a comma-delimited list as a parameter and returns the values of that list into a table variable.
*/
@mylist varchar(8000)
)
RETURNS @ListTable TABLE (
seqid int not null,
entry varchar(255) not null)
AS
BEGIN
DECLARE
@this varchar(255),
@rest varchar(8000),
@pos int,
@seqid int
SET @this = ' '
SET @seqid = 1
SET @rest = @mylist
SET @pos = PATINDEX('%,%', @rest)
WHILE (@pos > 0)
BEGIN
set @this=substring(@rest,1,@pos-1)
set @rest=substring(@rest,@pos+1,len(@rest)-@pos)
INSERT INTO @ListTable (seqid,entry) VALUES (@seqid,@this)
SET @pos= PATINDEX('%,%', @rest)
SET @seqid=@seqid+1
END
set @this=@rest
INSERT INTO @ListTable (seqid,entry) VALUES (@seqid,@this)
RETURN
END
在SQL Server数据库中运行该脚本以创建函数ListToTable。现在,您可以像这样重写查询:
@attributetypeid bigint,
@productid bigint,
@includedids varchar(MAX)
DELETE FROM reltable
WHERE productid = @productid AND
attributetypeid = @attributetypeid AND
attributeid NOT IN (SELECT entry FROM ListToTable(@includedids));
其中@includedids是您提供的逗号分隔列表。我在处理列表时一直使用此函数。请记住,此函数不一定要清理您的输入,它只是在逗号分隔列表中查找字符数据并将每个元素放入记录中。希望这会有所帮助。
答案 1 :(得分:1)
Joel Spolsky在这里回答了一个非常相似的问题:Parameterize an SQL IN clause
你可以尝试类似的东西,确保将你的attributetypeid转换为varchar。
答案 2 :(得分:1)
您无法将列表作为参数传递(AFAIK)。
你能否重写sql以使用子查询,如下所示:
delete from reltable
WHERE productid = @productid AND
attributetypeid = @attributetypeid AND
attributeid NOT IN (select id from ... where ... );
答案 3 :(得分:0)
可以将逗号分隔的列表发送到用户定义的函数,该函数将其作为简单表返回。然后可以通过NOT IN查询该表。 如果你需要fn,我可以提供..自从我使用sql以来已经大约5年了,我将不得不把我脑部的那部分弄脏......
答案 4 :(得分:0)
Erland拥有definitive guide来处理SQL 2005中的表列表,SQL 2008为您提供table based params。
在旁注中我会避免大型列表的NOT IN模式,因为它不会缩放,而是使用左连接。