2013-04-25 46 views
0

一段時間以來,我一直在搜索我的資源以重新分配Cursors SELECT語句,但沒有成功。重新分配遊標SELECT語句。 SQL Server 2008

首先讓我告訴你,到目前爲止我的代碼:

@KeyString - ID的逗號分隔的店鋪名單。
@Individual - 一次存儲單個ID @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一個新的SELECT語句。 ID_Cursor需要在循環後使用下一個@Individual。

有幾種方法我還以爲這是可能的:

  IF NOT ID_Cursor already exist Then 
      Create ID_Cursor 
      Else 
      Change ID Cursor 
      End 
  • 聲明ID_Cursor外循環和IF語句來替換整個(:如何它的代碼所示

    1. 'IF NOT CURSOR_STATUS('global,'ID_Cursor')> = -1)與:

        SET CURSOR FOR SELECT Blah FROM tbl_Blah WHERE Keyword = @Individual 
      
    2. 或者以某種方式刪除ID_Cursor,當它'回到'while 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

    我的項目是一個錯誤日誌系統,就像在Stack Overflow上使用標籤時一樣,用戶可以指定與他們的問題相關的錯誤關鍵字,以便在將來快速輕鬆地搜索相關問題。

    這個對數據庫的特殊調用是基於這些關鍵字的搜索。例如:用戶將在VB中選擇「電子郵件」和「Outlook」,然後@keystring將填入'4,6'。

    在這個例子中有2個關鍵字@keywords第一階段將它們分開成獨立Keyword_ID的。這是@Individual的用途。對於這個例子@individual = 4(對於第一個循環)。一旦我有了個人ID,我將需要運行'SELECT ID FROM tbl_Main WHERE Keyword_ID Like'%'+ @Individual +'%';'對於由此SELECT語句返回的每個ID,我需要檢查並查看ID已經出現在我的實踐中。如果它不存在,我將需要插入到temp_table(@individual (因爲這是來自tbl_main的ID),1 (因爲這是在temp_table中該ID的第一個實例))。例如:@individual = 4和錯誤,其中tbl_main中的ID = 1在Keyword_ID中包含'4',因此在temp_table中,ID將爲1並且計數爲1.

    在第二個循環@individual將會等於6(用戶正在搜索的第二個ID),因爲ID = 1的錯誤在我的temp_table中已經存在,並且它的Keyword_ID中包含'6',所以temp_table將需要更新而不是插入到(UPDATE Keyword_Count WHERE ID = @個人)一旦做到這一點特定的行會看起來像(1 | 2)(1,因爲它的ID | 2,因爲它包含 最後一次所有單獨的錯誤已經搜索了我將返回用戶所選擇的ID)的2 temp_table按Keyword_Count DESC排序,並使用此數據填充列表視圖。這意味着您正在搜索的最可能的錯誤將出現在列表中的第一位,因爲它會計算大多數搜索的關鍵字。

    所以,這就是我的總體目標:到返回tbl_main行其中包含最keyword_ID的搜索,首先由大排序。

  • +4

    什麼是您使用的是(醜陋,可怕的)光標一個簡單的'SELECT'聲明的原因是什麼? **最好的解決方案**將避免遊標開始 - 以**基於集合的方式編寫您的SQL代碼!** – 2013-04-25 10:21:13

    +0

    如果我可以實現我沒有遊標需要做的事情,我會非常樂意。 我需要從我的表格中返回關鍵字列包含@Individual的所有ID。對於每個返回的ID,我將它們添加到一個臨時表(臨時表包含2個collums ID,count)。此臨時表充當計數器,並且每次針對不同的關鍵字返回ID時,計數都會增加。解釋起來相當複雜,但我認爲可能的唯一方法就是使用遊標,所有幫助都將受到讚賞。 – 2013-04-25 10:33:02

    +1

    就像@marc_s說的。解釋問題以獲得幫助(並且從不使用遊標來實現任何事情)。所以基本上,描述源表和方式/頻率/等你得到這些「個人」球員和你想看到的結果。忘記你的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 – 2013-04-26 10:11:56

    +0

    不客氣;)留意潛在的SQL注入的情況下,SP將成爲大衆/人口和輸入可能PARAMS可以通過第三方來操作。這是一個全球性的規則,而不僅僅是這個SP。我之前做的是函數調用在連接之前測試輸入參數(查看它是否有'SELECT','DELETE','DROP'等關鍵字) – 2013-04-26 11:16:53