从ID不在ID列表中的表中选择

时间:2019-10-14 17:21:34

标签: sql-server tsql sql-server-2005

我正在尝试从primary_noVARCHAR(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'

我找到了解决这个问题的方法,我在下面回答。

2 个答案:

答案 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, ','))