2

SQL Server 2008で、一時テーブルのデータを既存のテーブルに挿入するプロシージャを作成しようとしています。私はそれをかなり理解したと思います、私はループに問題があるだけです。ループをいつ終了するかを決定するには、一時テーブルの行数が必要です。

@@ROWCOUNTを2つの異なる方法で使用してみました。WHILEステートメントでそれ自体を使用し、最初のループが終了したときに値を保持しようとする変数を作成します(以下のコードを参照)。

これらの方法はどちらもうまくいきませんでした、そして私は今何をすべきかについて途方に暮れています。この状況で@@ROWCOUNTを使用することは可能ですか、それとももっとうまくいく別の方法がありますか?

CREATE PROCEDURE InsertData(@KeywordList varchar(max))
AS
BEGIN

--create temp table to hold words and weights
CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL); 

DECLARE @K varchar(10), @Num int, @ID int

SET @KeywordList= LTRIM(RTRIM(@KeywordList))+ ','
SET @Num = CHARINDEX(',', @KeywordList, 1)
SET @ID = 0

--Parse varchar and split IDs by comma into temp table
IF REPLACE(@KeywordList, ',', '') <> ''
BEGIN
    WHILE @Num > 0
    BEGIN
        SET @K= LTRIM(RTRIM(LEFT(@KeywordList, @Num - 1)))
        SET @ID = @ID + 1
        IF @K <> ''
        BEGIN
            INSERT INTO #tempKeywords VALUES (@ID, @K) 
        END
        SET @KeywordList = RIGHT(@KeywordList, LEN(@KeywordList) - @Num)
        SET @Num = CHARINDEX(',', @KeywordList, 1)
        --rowcount of temp table
        SET @rowcount = @@ROWCOUNT
    END
END

--declaring variables for loop
DECLARE @count INT
DECLARE @t_name varchar(30)
DECLARE @key varchar(30)
DECLARE @key_weight DECIMAL(18,2)
--setting count to start from first keyword
SET @count = 2
--setting the topic name as the first row in temp table
SET @t_name = (Select keyword from #tempKeywords where ID = 1)
--loop to insert data from temp table into Keyword table
WHILE(@count < @rowcount)
    BEGIN
        SET @key = (SELECT keyword FROM #tempKeywords where ID = @count)
        SET @key_weight = (SELECT keyword FROM #tempKeywords where ID = @count+2)
        INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
        VALUES(@t_name,@key,@key_weight)
        SET @count= @count +2
    END 
--End stored procedure  
END
4

3 に答える 3

1

問題の2番目の部分を解決するには:

INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
SELECT tk1.keyword, tk2.keyword, tk3.keyword
FROM
    #tempKeywords tk1
        cross join
    #tempKeywords tk2
        inner join
    #tempKeywords tk3
        on
           tk2.ID = tk3.ID - 1
WHERE
    tk1.ID = 1 AND
    tk2.ID % 2 = 0

--declaring variables for loop(このコードは、コメント以降の現在のスクリプトのすべてを置き換える必要があります)

于 2012-10-11T07:33:43.740 に答える
0

変更できます:

WHILE(@count < @rowcount)

WHILE(@count < (select count(*) from #tempKeywords))

しかし、marc_sがコメントしたように、whileループなしでこれを実行できるはずです。

于 2012-10-11T07:16:47.417 に答える
0

行ごとではなく、セットベースの方法でこれを実行できるかどうかを確認するために、クエリを作り直すことを検討します。

あなたが達成しようとしていることを正確に実行できるかどうかはわかりませんが、ROW_NUMBER()関数を調べて一時テーブルのIDを設定したいと思います。この回答に示されているような再帰CTEとともに使用すると、空でないトリミングされた単語ごとにIDを取得できます。例は次のようなものです。

DECLARE @KeywordList varchar(max) = 'TEST,WORD, ,,,LIST, SOME , WITH, SPACES'

CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL) 

;WITH kws (ord, DataItem, Data) AS(
    SELECT CAST(1 AS INT), LEFT(@KeywordList, CHARINDEX(',',@KeywordList+',')-1) ,
    STUFF(@KeywordList, 1, CHARINDEX(',',@KeywordList+','), '') 
    union all
    select ord + 1, LEFT(Data, CHARINDEX(',',Data+',')-1),
        STUFF(Data, 1, CHARINDEX(',',Data+','), '')
        from kws
        where Data > ''
), trimKws(ord1, trimkw) AS (
    SELECT ord, RTRIM(LTRIM(DataItem)) 
    FROM kws
) 
INSERT INTO #tempKeywords (ID, keyword) 
SELECT ROW_NUMBER() OVER (ORDER BY ord1) as OrderedWithoutSpaces, trimkw 
FROM trimKws WHERE trimkw <> '' 

SELECT * FROM #tempKeywords

クエリの2番目の部分で何を達成しようとしているのか完全には理解していませんが、これに基づいて残りの部分を機能させることができます。少なくともwhileステートメントがなくても、自分が求めていることを実行できるように見えます。

于 2012-10-11T07:50:05.170 に答える