我有一个函数可以得到两个ID列表,我想要找回差异的数量。如果两个列表相等,则为0,否则为计数。
我将致电:
SELECT [dbo].[Redline_compareBaseProjSuccessors]
( '2498,2502,2510,2521,2841',
'2498,2502,2510,2521,2532,2820,2841') as isDifferent
我的职能是:
ALTER FUNCTION [dbo].[Redline_compareBaseProjSuccessors] (@projSuccessors varchar,@baseSuccessors varchar)
RETURNS int
AS
BEGIN
DECLARE @proj_assignment_ids TABLE (obj_id int)
DECLARE @base_assignment_ids TABLE (obj_id int)
DECLARE @is_different int
INSERT INTO @base_assignment_ids
SELECT base_assignment_id as obj_id
FROM base_assignment
WHERE base_assignment_id IN (@baseSuccessors)
INSERT INTO @proj_assignment_ids
SELECT base_assignment_id AS obj_id
FROM proj_assignment
WHERE proj_assignment_id IN (@projSuccessors)
SELECT @is_different = Count(obj_id)
FROM @base_assignment_ids
WHERE obj_id NOT IN (SELECT obj_id FROM @proj_assignment_ids)
RETURN @is_different
END
@base_assignment_ids
的值是:2498,2502,2510,2521,2841,2532,2820
和@proj_assignment_ids
= 2498,2502,2510,2521,2841
的值,所以我希望 2 作为返回值,但是我得到 0
出了什么问题?
答案 0 :(得分:0)
您无法在in
运算符中使用字符串而不是值列表。即:
... in ('1, 2, 3')
与:
不同... in (1, 2, 3)
您必须将该字符串转换为值列表,或者在字符串中查找id的字符串表示形式。
第二种很容易做到,但效率不高:
insert into @base_assignment_ids
select base_assignment_id as obj_id
from base_assignment
where
CHARINDEX(
',' + cast(base_assignment_id as varchar) + ',',
',' + @baseSuccessors + ','
) <> 0
答案 1 :(得分:0)
您需要稍微修改插入脚本
ALTER FUNCTION [dbo].[Redline_compareBaseProjSuccessors] (@projSuccessors varchar,@baseSuccessors varchar)
RETURNS int
AS
BEGIN
DECLARE @proj_assignment_ids TABLE (obj_id int)
DECLARE @base_assignment_ids TABLE (obj_id int)
DECLARE @is_different int
INSERT INTO @base_assignment_ids
SELECT base_assignment_id as obj_id
FROM base_assignment
WHERE base_assignment_id IN (
SELECT
Split.a.value('.', 'int') AS String
FROM (SELECT
CAST ('<M>' + REPLACE(@baseSuccessors, ',', '</M><M>') + '</M>' AS XML) AS String
) AS A CROSS APPLY String.nodes ('/M') AS Split(a))
INSERT INTO @proj_assignment_ids
SELECT base_assignment_id AS obj_id
FROM proj_assignment
WHERE proj_assignment_id IN ( SELECT
Split.a.value('.', 'int') AS String
FROM (SELECT
CAST ('<M>' + REPLACE(@projSuccessors, ',', '</M><M>') + '</M>' AS XML) AS String
) AS A CROSS APPLY String.nodes ('/M') AS Split(a))
SELECT @is_different = Count(obj_id)
FROM @base_assignment_ids
WHERE obj_id NOT IN (SELECT obj_id FROM @proj_assignment_ids)
RETURN @is_different
END
答案 2 :(得分:-1)
我发现了这个Convert String to Int List,但它对我的情况不起作用。
ALTER FUNCTION [dbo].[Redline_compareBaseProjSuccessors] (@projSuccessors nvarchar(max),@baseSuccessors nvarchar(max))
RETURNS int
AS
BEGIN
DECLARE @proj_assignment_ids TABLE (obj_id int)
DECLARE @base_assignment_ids TABLE (obj_id int)
DECLARE @is_different int
INSERT INTO @base_assignment_ids
SELECT base_assignment_id as obj_id from base_assignment where base_assignment_id in (dbo.fnStringList2Table(@base_assignment_ids))
INSERT INTO @proj_assignment_ids
select base_assignment_id as obj_id from proj_assignment where proj_assignment_id in (dbo.fnStringList2Table(@proj_assignment_ids))
SELECT @is_different=Count(obj_id)
FROM @base_assignment_ids
WHERE obj_id NOT IN (SELECT obj_id FROM @proj_assignment_ids)
RETURN @is_different
END
,函数fnStringListToTable如下所示:
ALTER FUNCTION [dbo].[fnStringList2Table]
(
@List varchar(MAX)
)
RETURNS
@ParsedList table
(
item int
)
AS
BEGIN
DECLARE @item varchar(800), @Pos int
SET @List = LTRIM(RTRIM(@List))+ ','
SET @Pos = CHARINDEX(',', @List, 1)
WHILE @Pos > 0
BEGIN
SET @item = LTRIM(RTRIM(LEFT(@List, @Pos - 1)))
IF @item <> ''
BEGIN
INSERT INTO @ParsedList (item)
VALUES (CAST(@item AS int))
END
SET @List = RIGHT(@List, LEN(@List) - @Pos)
SET @Pos = CHARINDEX(',', @List, 1)
END
RETURN
END
但它抛出(翻译自德语) 未找到dbo-column或用户定义的函数或用户定义的聚合'dbo.fnStringList2Table',或者用户名不是唯一/重复的。