2014-09-26 56 views
0

我有一個函數可以得到兩個ID列表,我想要返回差異計數。如果兩個列表相等,則爲0,否則爲計數。T-SQL獲得兩個表之間差異的計數

這我會叫:

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的價值,所以我期望作爲回報價值,但我得到

出了什麼問題?

+0

如果要創建的2個逗號分隔字符串可能是更爲有效的,以完全避免他們和解決這個問題以不同的方式 – 2014-09-26 09:07:29

+0

我不知道,但我認爲你的函數參數沒有很好地定義你已經設置了varchar,我認爲它們應該有一個長度,即varchar(100) – 2014-09-26 09:08:09

回答

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 
+0

是的,我確定使用不同的數據類型。我現在改成'[dbo]。[Redline_compareBaseProjSuccessors](@projSuccessors nvarchar,@ baseSuccessors nvarchar)'和'SELECT base_assignment_id作爲obj_id from base_assignment where base_assignment_id in('+ @ baseSuccessors +')'但現在它拋出一個'Error將varchar'+ @ baseSuccessors +'轉換爲int類型 – 2014-09-26 09:19:42

+0

@AlexanderDiedler:'varchar'和'nvarchar'之間的區別並不是問題,而是您嘗試使用字符串作爲SQL代碼。您不能使用字符串連接來將字符串用作SQL代碼。如果你想在代碼中使用字符串,那麼你必須把整個查詢放在一個字符串中,然後執行該字符串。 – Guffa 2014-09-26 13:35:14

-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的列或用戶definied功能或用戶定義的聚合「dbo.fnStringList2Table」找不到,或者用戶名不是唯一的/重複的。

+0

這應該很好地將字符串轉換爲值列表。從錯誤消息看來,該函數不存在。檢查你是否創建了它,並確保它在正確的數據庫中結束。 – Guffa 2014-09-26 13:39:49

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 
相關問題