2009-07-01 4 views
0

Каков самый быстрый способ для цикла через запрос в T-SQL. 1) Курсоры или 2) Таблицы Temp с добавленным ключом или все остальное.Самый быстрый способ петли через SQL-запрос

+1

Что вы пытаетесь достичь? –

+0

Я получаю некоторые данные из запроса и хочу прокручивать через 1-й по последний элемент и выполнять конкатенацию строк в результирующем наборе. – Greens

+0

Основное правило: избегайте курсоров, когда это возможно - они мертвы - медленные, неуклюжие и просто не подходят для T-SQL. Вместо этого используйте наборный подход - загрузите его в таблицу temp и запустите на нем инструкцию UPDATE. –

ответ

0

Я не думаю, что для этого вам нужен курсор (ваш комментарий о concat), если я пойму, для чего вы идете. Вот один из моих, который захватывает все номера телефонов для контакта и шлепает их в поле и возвращает его.

DECLARE @numbers VARCHAR(255) 

SELECT @numbers = COALESCE(@numbers + ' | ','') + PHONE_NUMB FROM my_table (NOLOCK) 
WHERE [email protected]_id RETURN @numbers 
+0

Как добавить оператор case Пример Например, если мой формат номера телефона является Интернационалом, добавьте международный контакт и т. д. Как пример. – Greens

+0

Это просто нормальный SQL. Вы можете использовать типичный синтаксис запроса. DECLARE @RET VARCHAR (4192) ВЫБРАТЬ @RET = COALESCE (@RET + '|', '') + LTRIM (COALESCE ( \t CONTACT_FIRST_NAME + '' + CONTACT_LAST_NAME, \t CONTACT_REF, \t CONTACT_COMP_NAME) + ISNULL ('' + CONTACT_SSN, '') ) FROM my_table WHERE my_conditions RETURN @RET – Nikki9696

+0

Как использовать заявление CASE здесь .IS это возможно? – Greens

1

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

+0

lol. любые факторы, чтобы рассмотреть, какой из них реализовать. – Greens

+0

Размер таблицы является основным фактором – northpole

0

Курсоры обычно являются ресурсоемкими, особенно при увеличении размера стола. Поэтому, если размер вашей таблицы невелик, мне было бы лучше рекомендовать курсор, однако большая таблица, вероятно, улучшилась бы с внешней или временной таблицей.

5

Самый быстрый способ «петлировать» через запрос - просто не делать этого. В SQL вы должны думать о наборе, а не о петле. Вероятно, вы должны оценить свой запрос, спросить, почему вам нужно зациклиться, и искать способы сделать это как набор.

С учетом сказанного, использование опции FAST_FORWARD на ваших курсорах поможет ускорить работу.

0

Вы хотите выполнить цикл вывода запроса внутри хранимой процедуры ИЛИ из кода на C#?

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

0

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

+0

переменные таблицы могут также находиться в tempdb - http://blogs.msdn.com/sqlserverstorageengine/archive/2008/03/30/sql-server-table-variable-vs-local-temporary -table.aspx –

3

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

declare @table table 
(
    ID int 
) 

insert into @table select 1 union select 2 union select 3 union select 4 union select 5 

declare @concat varchar(256) 

-- Add comma if it is not the first item in the list 
select @concat = isnull(@concat + ', ', '') + ltrim(rtrim(str(ID))) from @table order by ID desc 

-- or do whatever you want with the concatenated value now... 
print @concat 
+0

+1 для рабочего кода –

0

Вот ярлык для получения строки с разделителями-запятыми из одного поля из запроса, который возвращает несколько строк. Довольно быстрый по сравнению с альтернативами курсоров и т. Д., И он может быть частью подзапроса (т. Е. Получить некоторые вещи и в одном столбце идентификаторы всех вещей, связанных с каждой вещью в какой-либо другой таблице):

SELECT 
    COALESCE(
     REPLACE(
     REPLACE(
      REPLACE(
     (SELECT MyField AS 'c' FROM [mytable] FOR XML PATH('')),'</c><c>',','), 
      '<c>',''), 
     '</c>',''), 
     '') 
    AS MyFieldCSV 

Предостережение: он не будет играть хорошо, если в вашем столбце содержатся символы, которые FOR XML PATH сбегут.

0

Курсор не хорошо избегать курсора и использовать во время цикла вместо курсора таблицы Temp с ключом добавляемого лучший способ использования цикла.

Мне нужно манипулировать более 1000000 строк в таблице и для курсора занимает 2 минуты из-за сложной логики. , но при преобразовании курсора в цикл while это займет 25 секунд. так что это большая разница в исполнении.

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