Вставьте кавычки в каждое слово в строке sql, разделенной запятыми, и используйте в функции SQL

#sql #sql-server #tsql #stored-procedures #sql-function

#sql #sql-server #tsql #хранимые процедуры #sql-функция

Вопрос:

У меня есть строка, подобная этой:

 @Values VARCHAR(1000)
SET @Values = 'one, two, three'
 

Я хочу использовать эту строку в WHERE предложении с IN оператором.

Для этого я использую следующую табличную функцию.

 ALTER FUNCTION [dbo].[FN_RPT_CommaSeperated] 
    (@StringInput VARCHAR(8000), 
     @Delimiter NVARCHAR(1))
RETURNS @OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN
    DECLARE @String VARCHAR(10)

    WHILE LEN(@StringInput) > 0
    BEGIN
        SET @String = LEFT(@StringInput, 
                           ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
                           LEN(@StringInput)))
        SET @StringInput = SUBSTRING(@StringInput,
                                     ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput), 0),
                                     LEN(@StringInput))   1, LEN(@StringInput))

        INSERT INTO @OutputTable ([String])
        VALUES (''''   @String   '''')
    END

    RETURN
END
 

Эта функция возвращает значения ожидаемым образом. Но все же моя хранимая процедура не выдает данные, как ожидалось.

В хранимой процедуре, которую я использую следующим образом:

   WHERE
      TD.CaseId IN (SELECT * FROM [FN_RPT_CommaSeperated] (@Values,','))
 

В любом случае, когда я жестко кодирую подобные значения в хранимой процедуре, она возвращает ожидаемый результат.

 WHERE
    TD.CaseId IN ('one', 'two', 'three')
 

Есть идеи, как получить результат с помощью функции?

Ответ №1:

Уже есть функция с табличным значением, встроенная в SQL Server, начиная с SQL Server 2016. String_Split

 DECLARE @Values VARCHAR(1000)
SET @Values = 'one, two, three'
SELECT value FROM STRING_SPLIT(@Values, ',');
 

Вы можете сделать что-то вроде приведенного ниже:

 WHERE
    TD.CaseId IN (SELECT value FROM STRING_SPLIT(@Values));
 

Ответ №2:

Вы близки, но поскольку теперь у вас есть таблица, вы можете использовать что-то вроде:

 WHERE exists
   (select * from [FN_RPT_CommaSeperated] (@Values,',') where [string]=TD.CaseId)
 

Комментарии:

1. Я не понял здесь часть «where [string]= TD.CaseID». почему это используется?

2. Что здесь [строка] ?

3. Это имя столбца, возвращаемого вашей функцией.

4. Когда я использую это снова, ничего не возвращается. Но если я использую только это, всегда возвращаются данные для всех регистров. ГДЕ существует (выберите * из [FN_RPT_CommaSeperated] (@Values,’,’)

5. Мне удалось получить данные, используя предложение ur и небольшое изменение функции.

Ответ №3:

Я немного изменил функцию и предложение WHERE в SP, чтобы получить ожидаемый результат. Это работает нормально.

 ALTER FUNCTION [dbo].[FN_RPT_CommaSeperated] 
(@StringInput VARCHAR(8000), 
 @Delimiter NVARCHAR(1))
RETURNS @OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN
DECLARE @String VARCHAR(10)

WHILE LEN(@StringInput) > 0
BEGIN
    SET @String = LEFT(@StringInput, 
                       ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
                       LEN(@StringInput)))
    SET @StringInput = SUBSTRING(@StringInput,
                                 ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput), 0),
                                 LEN(@StringInput))   1, LEN(@StringInput))

    **INSERT INTO @OutputTable ([String])
    VALUES (@String)**
END

RETURN
END
 

В хранимой процедуре изменилось следующим образом.

 WHERE 
**exists
(select * from [FN_RPT_CommaSeperated_Kiosk] (@KioskId,',') where [String] = TD.CaseId)**
 

Ответ №4:

Вам нужно небольшое изменение в вашей функции

 ALTER FUNCTION [dbo].[FN_RPT_CommaSeperated] 
    (@StringInput VARCHAR(8000), 
     @Delimiter NVARCHAR(1))
RETURNS @OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN
    DECLARE @String VARCHAR(10)

    WHILE LEN(@StringInput) > 0
    BEGIN
        SET @String = LEFT(@StringInput, 
                           ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
                           LEN(@StringInput)))
        SET @StringInput = SUBSTRING(@StringInput,
                                     ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput), 0),
                                     LEN(@StringInput))   1, LEN(@StringInput))

        INSERT INTO @OutputTable ([String])
        VALUES (''   @String   '')
    END

    RETURN
END
 

используйте VALUES ('' @String '') вместо VALUES ('''' @String '''')