0

しばらくの間、カーソルの SELECT ステートメントを再割り当てする方法を探していましたが、成功しませんでした。

まず、これまでのコードをお見せしましょう。

@KeyString - コンマで区切られた ID のリストを保存します。
@Individual - @KeyString が分割されると、個々の ID が格納されます。

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 を使用する必要があります。

これが可能だと私が考えていたいくつかの方法があります:

  1. コードでの表示方法:

                IF NOT ID_Cursor already exist Then
                Create ID_Cursor
                Else
                Change ID Cursor
                End
    
  2. ループの外側で ID_Cursor を宣言し、IF ステートメント全体 ('IF NOT CURSOR_STATUS('global, 'ID_Cursor')>= -1) を次のように置き換えます。

                SET CURSOR FOR SELECT Blah FROM tbl_Blah WHERE Keyword = @Individual
    
  3. または、ID_Cursor が 'While LEN(@KeyString) > 1' に戻るときに ID_Cursor を削除し、毎回宣言しますか?

問題は、カーソルの再割り当てと再実行に関するドキュメント/構文をまだ見つけていないことです。再割り当てする前に、最初にカーソル データをクリアする必要がありますか?


テーブル構造:

Tbl_Main (ID int、Error_Title varchar、Error_Description varchar、K_ID varchar)

行の例: 1 | メールが送信されない | 管理者に連絡してください | 4、6

Tbl_Keyword(ID int, Keyword varchar) 行の例:

4 | メール

6 | 見通し

Temp_Table(Main_ID int, Keyword_Count int)ローカル一時テーブルは、その 1 つの接続に対してのみ存在します

行の例: 1 | 2

私のプロジェクトはエラー ログ システムです。スタック オーバーフローでタグを使用する場合と同じように、ユーザーは自分の問題に関連するエラー キーワードを割り当てて、将来関連する問題をすばやく簡単に検索できるようにします。

データベースへのこの特定の呼び出しは、これらのキーワードに基づく検索です。例: ユーザーが VB で「Emails」と「Outlook」を選択すると、@keystring に「4, 6」が入力されます。

この例では、@keywords に 2 つのキーワードがあるため、最初の段階ではそれらを個々の Keyword_ID に分割します。これが @Individual の用途です。この例では @individual = 4 (最初のループ)。個人 ID を取得したら、「SELECT ID FROM tbl_Main WHERE Keyword_ID Like '%' + @Individual + '%';」を実行する必要があります。この SELECT ステートメントによって返される ID ごとに、その ID が temptable に既に存在するかどうかを確認する必要があります。まだ存在しない場合は、INSERT INTO temp_table (@individual (これは tbl_main からの ID であるため)、1 (これは temp_table 内のこの ID の最初のインスタンスであるため) に挿入する必要があります))。例: @individual = 4 で、tbl_main の ID = 1 のエラーには Keyword_ID に「4」が含まれているため、temp_table では ID は 1 になり、カウントは 1 になります。

2 番目のループでは、@individual は 6 (ユーザーが検索している 2 番目の ID) に等しいため、ID = 1 のエラーが既に temp_table に存在し、その Keyword_ID に '6' が含まれているため、temp_table を更新する必要はありません。 Inserted Into (UPDATE Keyword_Count WHERE ID = @Individual) これが完了すると、この特定の行は (1 | 2) (ID であるため 1 | ユーザーが選択した ID が 2 つ含まれているため 2) のようになります。エラーが検索されました。Keyword_Count DESC で並べ替えられた temp_table を VB に返し、リスト ビューにこのデータを入力します。これは、検索されたほとんどのキーワードが含まれているため、検索している可能性が最も高いエラーがリストの最初に表示されることを意味します。

それが私の全体的な目的です。検索された最も多くのkeyword_IDを含むtbl_mainの行を、最初に最大順に並べて返すことです。

4

1 に答える 1

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 の「新しいクエリ」ウィンドウ) で試すことができます。正しくない場合はお知らせください。その理由を説明し、他に必要な結果を教えてください。

于 2013-04-25T14:12:47.713 に答える