2010-07-27 3 views
1

Я пытаюсь сделать выбор, как это:Как получить много строк на основе нескольких уникальных идентификаторов?

DECLARE @ContentIDs VARCHAR(MAX); 

SELECT @ContentIDs = 'e28faa48-adea-484d-9d64-ba1e1c67eea3,8338A6DE-8CDF-4F52-99CE-62E2B107FF97' 

SELECT * FROM [Content] WHERE [ID] IN (@ContentIDs) 

Это только возвращает содержимое с первым UNIQUEIDENTIFIER.

Как получить все строки?

ответ

4

Вы могли

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

  2. использовать разделенную функцию для разбора списка и добавить каждую запись в виде строки в табличную переменную, которую вы затем присоединяете к этому, или

  3. SELECT * FROM [Content] WHERE @ContentIDs like '%' + cast([ID] as varchar(36)) + '%' это приведет к полному сканированию, но если вы соответствуете многим строкам, это может иметь значение. (Edit, но если вы соответствие множество строк строка сравнения, вероятно, будет огромная!)

Вариант 2, как правило, мой предпочтительный подход. Или вы могли бы использовать CTE, чтобы сделать что-то подобное (на основании approach here)

DECLARE @ContentIDs VARCHAR(MAX); 

SET @ContentIDs = 'e28faa48-adea-484d-9d64-ba1e1c67eea3,8338A6DE-8CDF-4F52-99CE-62E2B107FF97'; 

WITH Guids(pn, start, [stop]) AS 
(
     SELECT 1, cast(1 as bigint), CHARINDEX(',', @ContentIDs) 
     UNION ALL 
     SELECT pn + 1, [stop] + 1, CHARINDEX(',', @ContentIDs, [stop] + 1) 
     FROM Guids 
     WHERE [stop] > 0 
) 

SELECT <collist> FROM 
[Content] 
WHERE [ID] IN (
    SELECT 
    CAST(LTRIM(RTRIM(SUBSTRING(@ContentIDs, start, 
     CASE WHEN [stop] > 0 
      THEN [stop]-start 
      ELSE LEN(@ContentIDs) END))) AS UNIQUEIDENTIFIER) 
    FROM Guids where [stop] > 0 or start>1 
    ) 
+0

Так как в этом случае я выиграл У меня более 15 идентификаторов, я думаю, я могу использовать опцию 3, ее довольно просто. Варианты 2 - идеальное решение, хотя я мог бы попробовать его когда-нибудь. – BrunoLM

1

Вы можете сделать сравнение строк с запятой списке:

SELECT * 
FROM [Content] 
WHERE ',' + @ContentIDs + ',' LIKE '%,' + CONVERT(varchar, [ID]) + ',%' 
1

Try:

SELECT @SQL = 'SELECT * FROM [Content] WHERE [ID] IN (' + @ContentIDs + ')' 
EXEC (@SQL) 
3

Это потому, что «IN» ожидает таблицу, и вы даете ей строку. Даже с «подобным», как предполагалось, это будет очень неряшливо, и ваши результаты не будут точными.

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

CREATE FUNCTION [dbo].[split] (

    @sourcestring varchar(8000), 
    @spliton varchar(1) 
) 

RETURNS @split table(value sql_variant) 

AS 
BEGIN 

    while (charindex(@spliton,@sourcestring)>0) 
     begin 
      insert into @split 
      select value = ltrim(rtrim(substring(@sourcestring,1,charindex(@spliton,@sourcestring)-1))) 

      set @sourcestring = substring(@sourcestring,charindex(@spliton,@sourcestring) + len(@spliton),len(@sourcestring)) 
     end 
    insert into @split select value = ltrim(rtrim(@sourcestring)) 

    RETURN 

END 

А потом называют это так:

DECLARE @ContentIDs VARCHAR(MAX); 

SELECT @ContentIDs = 'e28faa48-adea-484d-9d64-ba1e1c67eea3,8338A6DE-8CDF-4F52-99CE-62E2B107FF97' 

SELECT * FROM [Content] WHERE [ID] IN (select value from dbo.split(@ContentIDs,',')) 
+0

просто добавленное примечание, с sql 2005/2008, вы можете объявить @sourcestring с varchar (MAX), чтобы использовать более длинные строки, чем только 8000 символов. – AcidRaZor

+1

Результаты будут абсолютно точными. Все гиды имеют одинаковую длину и не могут содержать запятые. –

+0

верно, но позвольте мне объяснить, почему (мы надеемся, что дает вам представление о том, как я подошел и решил эту проблему несколько лет назад) если «12345» = «12345,67890,123456789» тогда «Сделайте что-нибудь конец, если Выше никогда не будет стрелять. Потому что то, что делает OP, сравнивает поле «12345» со строкой, содержащей более одного параметра. Невозможно, чтобы LIKE определял или разбивал строку несколькими частями, чтобы она могла вернуть любые действительные данные, на мой взгляд. Решение, которое я предоставил, используется в производстве с более чем 10 миллионами строк данных в одной таблице (и многих других таблицах) – AcidRaZor

Смежные вопросы