2013-04-25 3 views
0

Некоторое время я искал свои ресурсы, чтобы повторно назначить оператор Cursors SELECT без успеха.Повторное назначение оператора SELECT курсоров. SQL Server 2008

Прежде всего позвольте мне показать вам мой код до сих пор:

@KeyString - список магазинов ID разделённых запятой.
@Individual - сохраняет индивидуальный идентификатор, когда @KeyString разбит.

DECLARE @Keystring VarChar(100) = '4, 6' 
DECLARE @Individual VarChar(10) 

WHILE LEN(@KeyString) > 1 
BEGIN 

    IF PATINDEX('%, %', @KeyString) > 1 
    BEGIN 
    SET @Individual = SUBSTRING(@KeyString, 0, (PATINDEX('%, %', @KeyString))) 
    END 
    ELSE 
    BEGIN 
    SET @Individual = @KeyString 
    END 

    IF NOT CURSOR_STATUS('global', 'ID_Cursor')>= -1 
    BEGIN 
    DECLARE ID_Cursor Cursor 
    FOR 
    SELECT Blah FROM tbl_Blah WHERE ID = @Individual 
    OPEN ID_Cursor 
    END 
    ELSE 
    BEGIN 
    /*RESET ID_Cursor = SELECT Blah FROM tbl_Blah WHERE Keyword = @Individual 
    (The Next @Individual after first loop)*/ 
    END 

    FETCH NEXT FROM ID_Cursor INTO @blah 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     ...... 
     FETCH NEXT FROM ID_Cursor INTO @blah 
    END 
/*Loops Back to 'While LEN(@KeyString) > 1*/ 
END 

Как-то мне нужно назначить ID_Cursor новый ЗЕЬЕСТ. ID_Cursor должен использовать следующий @Individual, возвращенный после его зацикливания.

Есть несколько способов, я бы подумал, что это возможно:

  1. Как сво показано в коде:

      IF NOT ID_Cursor already exist Then 
          Create ID_Cursor 
          Else 
          Change ID Cursor 
          End 
    
  2. Declare ID_Cursor вне цикла и заменить весь Оператор IF ('ЕСЛИ НЕ CURSOR_STATUS (' global, 'ID_Cursor')> = -1) с:

      SET CURSOR FOR SELECT Blah FROM tbl_Blah WHERE Keyword = @Individual 
    
  3. Или каким-то образом удалите ID_Cursor, когда он «Циклы назад», пока LEN (@KeyString)> 1 »и объявляет его каждый раз?

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


Таблица структуры:

Tbl_Main (ID INT, Error_Title VARCHAR, error_description VARCHAR, K_ID VARCHAR)

Пример строки: 1 | Электронная почта не отправляется | Обратитесь к администратору | 4, 6

Tbl_Keyword (ID INT, ключевое слово VARCHAR) Пример строки:

4 | Электронная почта:

6 | Перспективы

Temp_Table (Main_ID INT, KEYWORD_COUNT INT) локальная временная таблица существует только для этого одно соединение

Пример строки: 1 | 2

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

Этот конкретный вызов в базе данных - это поиск по этим ключевым словам. Например: пользователь будет выбирать «Emails» и «Outlook» в VB, а затем @keystring будет заполнен «4, 6».

В этом примере, поскольку в @keywords есть 2 ключевых слова, первым этапом было бы разбить их на отдельные ключевые слова. Для этого используется @Individual. Для этого примера @individual = 4 (для первого цикла). После того, как у меня будет индивидуальный идентификатор, мне нужно будет запустить «SELECT ID FROM tbl_Main WHERE Keyword_ID Like«% »+ @Individual + '%'; 'Для каждого идентификатора, возвращаемого этим оператором SELECT, мне нужно будет проверить и посмотреть, уже присутствует в моей таблице. Если он еще не существует, мне нужно будет ввести INSERT INTO temp_table (@individual (потому что это ID от tbl_main), 1 (потому что это первый экземпляр этого ID в temp_table)). Например: @individual = 4 и Error, где ID = 1 в tbl_main содержит «4» в Keyword_ID, поэтому в temp_table идентификатор будет равен 1, а счет будет равен 1.

На втором цикле @ индивидуум будет равен 6 (второй идентификатор, который ищет пользователь), так как ошибка, в которой ID = 1 уже существует в моей temp_table, и она содержит «6» в своем ключевом_имени, temp_table нужно будет обновить не вставлять в (UPDATE Keyword_Count ГДЕ ID = @ Индивидуальный), как только это будет сделано, эта конкретная строка будет выглядеть как (1 | 2) (1, потому что это ID | 2, потому что она содержит 2 идентификатора, выбранных пользователем) Наконец, после того, как все индивидуальные ошибки были найдены, я вернусь temp_table, упорядоченная по Keyword_Count DESC на VB, и заполняет представление списка этими данными. Это означает, что наиболее вероятная ошибка, которую вы ищете, будет отображаться 1-го в списке, так как в ней используется большинство ключевых слов.

Так что моя общая цель: вернуть строку в tbl_main, которая содержит наибольшее количество искомых ключевых слов.

+4

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

+0

Если бы я смог добиться того, что мне нужно, чтобы обойтись без курсоров, я был бы более чем счастлив , Мне нужно вернуть все ID из моей таблицы, где столбец ключевого слова содержит @Individual. Когда каждый из этих идентификаторов возвращается, я добавляю их в таблицу temp (таблица temp содержит 2 идентификатора совпадений, count). Эта временная таблица действует как подсчет, и каждый раз, когда идентификатор возвращается для другого ключевого слова, счет увеличивается. Это довольно сложно объяснить, но единственный способ, которым я вижу это, - использовать курсоры, вся помощь будет оценена. –

+1

Как и @marc_s. Объясните проблему, чтобы получить помощь (и никогда не используйте курсоры для чего-либо). Итак, в основном, описывайте исходную таблицу и способ/частоту/etc, вы получаете этих «индивидуальных» парней и результаты, которые вы хотите увидеть. Забудьте о своем SP выше. Опишите реальную проблему. – 2013-04-25 11:52:43

ответ

2

Спасибо за ответ. Так. Забудьте свой SP. Это то, что вам нужно, если я понял проблему:


DECLARE @keystrings varchar(max)
SET @keystrings='4, 6' --your example SET @keystrings=REPLACE(@keystrings, ' ', '') --remove spaces, we don't need them SET @keystrings=CONCAT('SELECT ', REPLACE(@keystrings, ',', ' UNION ALL SELECT '))
SELECT TBM.ID, count(TBM.ID) AS 'HitCount' FROM Tbl_Main AS TBM WHERE TBM.K_ID IN (@keystrings) GROUP BY TBM.ID

Вы можете попробовать это в ближайшем окне (окно "Новый запрос SSMS"). Дайте мне знать, если это неправильно, и объясните, почему/какие другие результаты вам нужны.

+0

Спасибо! Мой код уменьшился с 80 строк до 10. –

+0

Добро пожаловать;) Следите за потенциальными SQL-инъекциями в случае, если SP станет общедоступным/заполненным, а параметры ввода, возможно, могут быть обработаны третьей стороной. Это глобальное правило, а не только этот SP. То, что я использовал, - это входные параметры тестирования вызова функции перед конкатенацией (чтобы увидеть, есть ли в нем ключевые слова «SELECT», «DELETE», «DROP» и т. Д.), – 2013-04-26 11:16:53

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