T-SQL:有没有办法检查另一个变量中是否存在一个变量的值

时间:2017-09-12 04:15:44

标签: sql-server tsql variables

代码:

Declare @a VARCHAR(100) = ';2;9;12;13;14;16;17;21;'
Declare @b VARCHAR(100) = ';2;12;13;'
Declare @c VARCHAR(100)
While len(@a) > 1
Begin
    Set @c = substring(@a,1,charindex(';',@a,2))
    Set @b += @c Where @c Not In @b  ----This statement gives a problem and shows a syntax error
    Set @a = substring(@a,charindex(';',@a,2),len(@a))
    Select @a, @b, @c
End

我在这里要完成的是我已经声明了2个VARCHAR类型的变量并为它们分配了一些值。我声明的第三个变量是从第一个变量派生的子串。第三个变量的值我试图找到它存在于第二个变量中,如果它不是我试图将它与第二个变量连接起来。

所以@c得到的第一个值是:'; 2;'它应该与@b进行比较,如果不存在于@b中,它应该与@b连接。

所以基本上结果应该看起来像这样。

@b ='; 2; 12; 13; 9; 14; 16; 17; 21;'

请帮助。感谢。

5 个答案:

答案 0 :(得分:1)

如果我理解你的问题,我相信你会想要使用集合(表格)而不是字符串。如果使用拆分函数绝对必要,你可以使用字符串执行此操作(存在于SQL Server 2016中,但必须为以前的版本编写自己的版本.S.O上有大量示例。)

要使用套装,请尝试以下方法:

DECLARE @a TABLE (id INT identity(1, 1), val INT)
DECLARE @b TABLE (Val INT)
DECLARE @c INT
DECLARE @aSetStr VARCHAR(max)
DECLARE @bSetStr VARCHAR(max)

INSERT INTO @a
VALUES (2), (9), (12), (13), (14), (16), (17), (21)

INSERT INTO @b
VALUES (2), (12), (13)

DECLARE @i INT = 0

WHILE EXISTS (
        SELECT A.id
        FROM @a A
        LEFT JOIN @b B
            ON A.Val = B.Val
        WHERE A.id > @i AND B.Val IS NULL
        )
BEGIN
    SELECT TOP 1 @i = A.id, @c = A.Val
    FROM @a A
    LEFT JOIN @b B
        ON A.Val = B.Val
    WHERE A.id > @i AND B.Val IS NULL
    ORDER BY A.id ASC

    IF NOT EXISTS (
            SELECT 1
            FROM @b B
            WHERE B.Val = @c
            )
        INSERT INTO @b (Val)
        SELECT @c

    SELECT @aSetStr = STUFF((
                SELECT ';' + CAST(val AS VARCHAR(max))
                FROM @a
                FOR XML PATH('')
                ), 1, 0, '') + ';'

    SELECT @bSetStr = STUFF((
                SELECT ';' + CAST(val AS VARCHAR(max))
                FROM @b
                FOR XML PATH('')
                ), 1, 0, '') + ';'

    SELECT @aSetStr AS [Set A], @bSetStr AS [Set B], cast(@C AS VARCHAR(255)) AS [Value of C]
END

这将产生

Set A                      Set B                     Value of C
-------------------------- ------------------------- ------------
;2;9;12;13;14;16;17;21;    ;2;12;13;9;               9

Set A                      Set B                     Value of C
-------------------------- ------------------------- ------------
;2;9;12;13;14;16;17;21;    ;2;12;13;9;14;            14

Set A                      Set B                     Value of C
-------------------------- ------------------------- ------------
;2;9;12;13;14;16;17;21;    ;2;12;13;9;14;16;         16

Set A                      Set B                     Value of C
-------------------------- ------------------------- ------------
;2;9;12;13;14;16;17;21;    ;2;12;13;9;14;16;17;      17

Set A                      Set B                     Value of C
-------------------------- ------------------------- ------------
;2;9;12;13;14;16;17;21;    ;2;12;13;9;14;16;17;21;   21

答案 1 :(得分:1)

TRY THIS CODE
    Declare @a VARCHAR(100) = ';2;9;12;13;14;16;17;21;'
    Declare @b VARCHAR(100) = ';2;12;13;'
    Declare @c VARCHAR(100)
    While len(@a) > 1
    Begin
        Set @c = substring(@a,1,charindex(';',@a,2))
            IF (@c) NOT IN (@b) begin
                Set @b += @c
            end

         Set @a = substring(@a,charindex(';',@a,2),len(@a))
        Select @a, @b, replace(@c,';','')
    End

答案 2 :(得分:1)

获得预期结果的另一种方法

Declare @a VARCHAR(100) = ';2;9;12;13;14;16;17;21;'
Declare @b VARCHAR(100) = ';2;12;13;'

DECLARE @Tempa TABLE (Value nvarchar(1000))
INSERT INTO @Tempa VALUES(@a)
DECLARE @Tempb TABLE (Value nvarchar(1000))
INSERT INTO @Tempb VALUES(@b)

;WITH cte 
     AS (SELECT Cast(dataa AS INT) AS DataA 
         FROM   (SELECT split.a.value('.', 'nvarchar(1000)') AS DataA 
                 FROM   (SELECT Cast('<S>' + Replace(value, ';', '</S><S>') + 
                                     '</S>' 
                                     AS 
                                     XML) AS 
                                Data 
                         FROM   @Tempa)AS A 
                        CROSS apply data.nodes('S') AS Split(a)) dt 
         WHERE  dt.dataa <> '' 
         UNION 
         SELECT Cast(dataa AS INT) AS DataA 
         FROM   (SELECT split.a.value('.', 'nvarchar(1000)') AS DataA 
                 FROM   (SELECT Cast('<S>' + Replace(value, ';', '</S><S>') + 
                                     '</S>' 
                                     AS 
                                     XML) AS 
                                Data 
                         FROM   @Tempb)AS A 
                        CROSS apply data.nodes('S') AS Split(a))dt 
         WHERE  dt.dataa <> '') 
SELECT ''';' + Stuff((SELECT '; '+Cast(dataa AS VARCHAR(10)) FROM cte ORDER BY 
       dataa 
       FOR xml path ('')), 1, 1, '') + ' ;''' AS ExpectedCResult 

结果

ExpectedCResult
---------------------------------
'; 2; 9; 12; 13; 14; 16; 17; 21 ;'

答案 3 :(得分:1)

如果您的值是唯一的,则可以使用UNION合并字符串:

    Declare @a VARCHAR(100) = ';2;9;12;13;14;16;17;21;'
    Declare @b VARCHAR(100) = ';2;7;12;13;'
    Declare @c VARCHAR(100)

    ;WITH 
    a AS
    (
        SELECT @a AS FIELD, SUBSTRING(@a, 1, CHARINDEX(';', @a)) AS num
        UNION ALL
        SELECT RIGHT(FIELD, LEN(FIELD)-LEN(num)), SUBSTRING(RIGHT(FIELD, LEN(FIELD)-LEN(num)), 1, CHARINDEX(';', RIGHT(FIELD, LEN(FIELD)-LEN(num))))
        FROM a
        WHERE FIELD != num
    ),
    b AS
    (
        SELECT @b AS FIELD, SUBSTRING(@b, 1, CHARINDEX(';', @b)) AS num
        UNION ALL
        SELECT RIGHT(FIELD, LEN(FIELD)-LEN(num)), SUBSTRING(RIGHT(FIELD, LEN(FIELD)-LEN(num)), 1, CHARINDEX(';', RIGHT(FIELD, LEN(FIELD)-LEN(num))))
        FROM b
        WHERE FIELD != num
    )
    SELECT @c = 
        (
        SELECT ';' + CAST(v.num AS VARCHAR)
        FROM (
            SELECT CAST(REPLACE(a.num, ';', '') AS INT) num
            FROM a
            WHERE a.num != ';'
            UNION 
            SELECT CAST(REPLACE(b.num, ';', '') AS INT)
            FROM b
            WHERE b.num != ';'
        ) v
        FOR XML PATH('')
        ) + ';'

SELECT @c

答案 4 :(得分:1)

要直接解决您的问题,请更改:

Set @b += @c Where @c Not In @b 

要:

SET @b += CASE WHEN CHARINDEX(@c, @b) > 0 THEN '' ELSE @c END