Select 来自 table 其中 ID 不在 ID 列表中
Select from table where ids are not in list of ids
我正在尝试从 table select 中 primary_no
(VARCHAR(20)
) 不包含 @IDS 变量中的任何字符串,但是它不工作,我试过使用 CTE,不存在也不在。它们都不起作用。查询仍然 select 所有数据,甚至是 @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'
我找到了解决这个问题的方法,我在下面回答。
免责声明:从 chat 可以看出,OP 使用的不是 2014 年,而是 2005 年(完全不受支持,多年来一直如此)。因此,使用 table 类型参数的答案将不起作用,因为该功能不存在。
不过,我已将答案留在那里,以供以后有类似问题的用户使用。
不使用定界列表,而是使用 table 类型的参数
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';
这就是我的问题的解决方案。 IDS 被解析为 table,我从那里选择。我的主要问题是我设置了格式不正确的@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, ','))
我正在尝试从 table select 中 primary_no
(VARCHAR(20)
) 不包含 @IDS 变量中的任何字符串,但是它不工作,我试过使用 CTE,不存在也不在。它们都不起作用。查询仍然 select 所有数据,甚至是 @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'
我找到了解决这个问题的方法,我在下面回答。
免责声明:从 chat 可以看出,OP 使用的不是 2014 年,而是 2005 年(完全不受支持,多年来一直如此)。因此,使用 table 类型参数的答案将不起作用,因为该功能不存在。
不过,我已将答案留在那里,以供以后有类似问题的用户使用。
不使用定界列表,而是使用 table 类型的参数
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';
这就是我的问题的解决方案。 IDS 被解析为 table,我从那里选择。我的主要问题是我设置了格式不正确的@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, ','))