5

レコードを取り出してそれぞれを文字列に連結し、その文字列を出力することになっている SQL クエリがあります。クエリの重要な部分は次のとおりです。

DECLARE @counter int;
SET @counter = 1;

DECLARE @tempID varchar(50);
SET @tempID = '';

DECLARE @tempCat varchar(255);
SET @tempCat = '';

DECLARE @tempCatString varchar(5000);
SET @tempCatString = '';

WHILE @counter <= @tempCount
BEGIN

    SET @tempID = (
    SELECT [Val]
    FROM #vals
    WHERE [ID] = @counter);

    SET @tempCat = (SELECT [Description] FROM [Categories] WHERE [ID] = @tempID);
    print @tempCat;

    SET @tempCatString = @tempCatString + '<br/>' + @tempCat;
    SET @counter = @counter + 1;

END

スクリプトが実行されると、常に正しく出力されますが、 @tempCatStringnull として出力されます。@tempCatWhileループ内で連結が機能しない理由はありますか? @counterインクリメントは完全に機能するため、それは間違っているようです。それで、私が見逃しているものは他にありますか?

4

3 に答える 3

7

それはうまくいくように見えますが、何らかの理由で @tempCatString が null であると考えているようです。COALESCE()null の場合は、各変数を " " に設定することをお勧めします。

于 2009-01-16T20:28:08.493 に答える
5

これはより効率的でしょう....

select @tempCatString = @tempCatString + Coalesce(Description,'') + '<br/>' from Categories...

select @fn

連結の問題を修正するオプションとして concat_null_yields_null も見てください。ただし、そのルートは避けます

于 2009-01-16T20:26:51.443 に答える
1

私はkeithwarrenに同意しますが、クエリには必ずORDERBY句を追加します。そうすれば、値が連結されている順序を正確に確認できます。

また、NULL値を''に置き換えるCOALESCEは、事実上空白行を生成します。それらが必要かどうかはわかりませんが、代わりにWHERE句でフィルタリングするだけではありません...

最後に、関心のあるIDを含む一時テーブルがあるように見えます。このテーブルをJOINに含めるだけで、ソーステーブルをフィルタリングできます...

DELCARE @output VARCHAR(8000)
SET @output = ''

SELECT
    @output = @output + [Categories].Description + '<br/>'
FROM
    Categories
INNER JOIN
    #vals
        ON #vals.val = [Categories].ID
WHERE
   [Categories].Description IS NOT NULL
ORDER BY
   [Categories].Description
于 2009-01-18T00:45:04.013 に答える