2015-11-16 2 views
0

Я пытаюсь использовать список возвращаемых каретой разделенных параметров в списке IN инструкции where моего запроса.Рассчитанный параметр в WHERE

Я могу превратить список в одну строку, разделенную запятой, в правильном формате с использованием функции replace, однако, когда я помещаю это в список IN, он ничего не возвращает.

Нижеприведенный запрос возвращает список, разделенный запятой, как ожидалось.

declare @VarCodes varchar(max) 
set @VarCodes = '123-1 
123-10 
123-100 
61 
66 
67 
75' 
(select ''''+replace(replace(REPLACE(@VarCodes,char(13),''''+', '+''''),char(32),''),char(10),'')+'''') 

'123-1', '123-10', '123-100', '61', '66', '67', '75'

Если я вставить этот текст непосредственно в запросе ниже он возвращает данные, как ожидалось.

select vad_variant_code from variant_detail where vad_variant_code in ('123-1','123-10','123-100','61','66','67','75') 

Если я ставлю параметр в in, она ничего не возвращает.

select vad_variant_code from variant_detail where vad_variant_code in ((select ''''+replace(replace(REPLACE(@VarCodes,char(13),''''+', '+''''),char(32),''),char(10),'')+'''')) 

Я предполагаю, что это происходит потому, что IN ожидает разделенный запятыми список строк, где, как функция replace возвращает одну длинную строку?

Возможно ли это?

+0

1) Динамический SQL 2) Таблица многозначного Параметр 3) Таблица значной функции разделение ... – lad2025

+0

Уход за разработкой? :) – OWSam

+0

Возможный дубликат [Определить переменную для использования с оператором IN (T-SQL)] (http://stackoverflow.com/questions/1707326/define-variable-to-use-with-in-operator-t-sql) – lad2025

ответ

1

Попробуйте это ...

declare @VarCodes varchar(max), @Xml XML; 
set @VarCodes = '123-1,123-10,123-100,61,66,67,75' 

SET @Xml = N'<root><r>' + replace(@VarCodes, ',','</r><r>') + '</r></root>'; 


select vad_variant_code from variant_detail 
where vad_variant_code in (
          select r.value('.','varchar(max)') as item 
          from @Xml.nodes('//root/r') as records(r) 
         ) 
+0

спасибо. Скорость здесь действительно не проблема, так как будет максимум 20 переменных. Я немного изменил ваш выбор, так как мой список не разделен символом, скорее возврат каретки. Не проблема, я просто изменил замену внутри XML-выборки. SET @xml = N ' '+ заменить (заменить (@ VarCodes, символ (10),' '), символ (13),' ') +''; – OWSam

0

У меня есть этот код в качестве ТВФА на основе первоначально на коде Джеффа Moden в:

CREATE FUNCTION [dbo].[cSplitter] (@Parameter VARCHAR(MAX)) 
RETURNS @splitResult TABLE (number INT, [value] VARCHAR(100)) 
AS 
BEGIN 
SET @Parameter = ','[email protected] +','; 

WITH cteTally AS 
    (
     SELECT TOP (LEN(@Parameter)) 
      ROW_NUMBER() OVER (ORDER BY t1.Object_ID) AS N 
      FROM Master.sys.All_Columns t1 
      CROSS JOIN Master.sys.All_Columns t2 
    ) 
INSERT @splitResult 
    SELECT ROW_NUMBER() OVER (ORDER BY N) AS Number, 
    SUBSTRING(@Parameter,N+1,CHARINDEX(',',@Parameter,N+1)-N-1) AS [Value] 
    FROM cteTally 
     WHERE N < LEN(@Parameter) AND SUBSTRING(@Parameter,N,1) = ',' 
RETURN 
END 

С этой ТВФОМ в моей базе данных, мои «В» запросах могут принимает разделенный запятыми список значений, как это:

DECLARE @VarCodes VARCHAR(MAX); 
SET @VarCodes = '123-1 
123-10 
123-100 
61 
66 
67 
75'; 

DECLARE @csv VARCHAR(MAX); 
SET @csv = REPLACE(REPLACE(REPLACE(@VarCodes, CHAR(13), ','), CHAR(32), ''), 
        CHAR(10), ''); 

SELECT vad_variant_code 
FROM variant_detail 
WHERE EXISTS (SELECT * 
       FROM [cSplitter](@csv) AS [cs] 
       WHERE [cs].[value] = vad_variant_code); 
+0

Это круто, но много боли для довольно простой задачи :(, я сделал все это в двух строках, см. Мой ответ :) –

+0

Имея меньше строк, это не значит, что это лучше. Вы используете xml, который я бы не предлагал в этом случае, плюс вы предполагаете, что это значение, разделенное запятой, но оно отсутствует (см. OP). На самом деле, я был ленив, чтобы добавить к этому больше, поскольку SQL-сервер очень медленный в строковых операциях, я бы действительно предложил создать TVF в качестве функции CLR (что я и делал в реальной жизни - есть огромная разница в производительности, с xml it хуже). –

+0

Истинный с меньшим количеством строк кода не означает, что он будет лучше в производительности, но код, который вы предложили, выполняет строковые манипуляции, по характеру, я считаю, что все будет быстрее, чем это :) –