我正在尝试从primary_no
(VARCHAR(20)
)不包含@IDS变量中的任何字符串的表中进行选择,但是它不起作用,因此我尝试使用CTE ,不存在也不存在。它们都不起作用。查询仍然会选择所有数据,即使@IDS变量中具有primary_no的那些数据。
ALTER PROCEDURE [dbo].[LinkProc]
@IDS VARCHAR(MAX)
/*
DECLARE @IDS VARCHAR(MAX)
SET @IDS = '
''00000447'',
''0000300'',
''2900071'',
''2900192''
'
EXEC LinkProc @IDS = @IDS
*/
AS
WITH cte (id) AS
(
SELECT *
FROM dbo.splitstring(@IDS)
)
SELECT *
FROM link_tb
WHERE grp_id = 4
AND status_cd = 'A'
AND primary_no NOT IN (SELECT id FROM cte)
我也没有运气尝试过这个
SELECT *
FROM link_tb lt
WHERE grp_id = 4
AND status_cd = 'A'
AND NOT EXISTS (SELECT id FROM cte c WHERE lt.primary_no = c.id)
调用(SELECT id FROM cte
)的结果集:
'00000447'
'0000300'
'2900071'
'2900192'
我找到了解决这个问题的方法,我在下面回答。
答案 0 :(得分:2)
免责声明:从chat中可以看出,OP不是使用2014,而是使用2005(完全不受支持,已经使用了很多年)。结果,使用表类型参数的答案将不起作用,因为该功能不存在。
但是,对于那些有类似问题的未来用户,我将答案留在那里。
使用表格类型参数代替使用分隔列表
CREATE TYPE dbo.PrimaryList AS TABLE (primary_no varchar(20) NOT NULL);
GO
ALTER PROC dbo.LinkProc @IDs dbo.PrimaryList READONLY AS
BEGIN
SELECT *
FROM dbo.link_tb l
LEFT JOIN @IDs I ON l.primary_no = I.primary_no
WHERE grp_id = 4
AND status_cd = 'A'
AND I.primary_no IS NULL;
END;
GO
然后可以这样调用SP:
DECLARE @IDs dbo.PrimaryList;
INSERT INTO @IDs
VALUES('00000447'),
('0000300'),
('2900071'),
('2900192');
EXEC dbo.LinkProc @IDs;
编辑: 至于为什么你的东西不起作用,那是因为你引用了包装你的价值观。您正在做的是等价的:
EXEC dbo.LinkProc @IDs = '''00000447''';
primary_no
的值将不会是'00000447'
,而只会是00000447
。如果您必须传递定界列表(我建议您反对,并且如果您的函数使用WHILE
,并且您是否需要,我也不会感到惊讶删除该值),则不要引用这些值:
EXEC dbo.LinkProc @IDs = '00000447,0000300,2900071,2900192';
答案 1 :(得分:0)
这是解决我的问题的方法。将IDS解析为一个表,然后从中选择一个表。我的主要问题是我设置了@IDS格式不正确,字符串中有换行符。将它们放在一起时没有任何空格。
ALTER PROCEDURE [dbo].[LinkProc]
@IDS VARCHAR(MAX)
/*
DECLARE @IDS VARCHAR(MAX)
SET @IDS = '00000447,0000300,2900071,2900192'
EXEC LinkProc @IDS = @IDS
*/
AS
SELECT *
FROM link_tb
WHERE grp_id = 4
AND status_cd = 'A'
AND primary_no NOT IN (SELECT param_value FROM dbo.PARSE_PARAM_LIST(@IDS, ','))