2010-12-15 9 views
1

次のスクリプトを参照してください。データを連結するためのテーブル上のループ(カーソルを使用しない)

DECLARE @Products Table ( PId int) 

INSERT @Products SELECT 100 
INSERT @Products SELECT 101 
INSERT @Products SELECT 102 

DECLARE @Stff Table (Stid int, StaffName VARCHAR(20)) 

INSERT @Stff SELECT 301, 'White' 
INSERT @Stff SELECT 302, 'Green' 

DECLARE @Items Table 
(
    ItemId int, 
    PIdFK int, 
    StIdFK int, 
    CreatedDate DateTime, 
    Notes varchar(100), 
    NotesHistory varchar(2000) 
) 

INSERT INTO @Items SELECT 1, 100, 301, GETDATE(), Null, NULL 
INSERT INTO @Items SELECT 2, 101, 301, GETDATE(), Null, NULL 
INSERT INTO @Items SELECT 3, 101, 301, DATEADD(DD, 1, GETDATE()), 'Hello Dear', NULL 
INSERT INTO @Items SELECT 4, 101, 301, DATEADD(DD, 2, GETDATE()), 'Did you get my msg?', NULL 
INSERT INTO @Items SELECT 5, 102, 302, GETDATE(), Null, NULL 
INSERT INTO @Items SELECT 6, 102, 302, DATEADD(DD, 1, GETDATE()), Null, NULL 
INSERT INTO @Items SELECT 7, 102, 302, DATEADD(DD, 3, GETDATE()), 'How are you doing?', NULL 
INSERT INTO @Items SELECT 8, 102, 302, DATEADD(DD, 4, GETDATE()), 'Your Items are ready.', NULL 

SELECT * FROM @Items 

DECLARE @ItemsHistory Table 
(
    ItemHisotryId int, 
    ItemIdFK int, 
    StIdFK int, 
    NotesHisotry varchar(200), 
    CreatedDate DATETIME 
) 

INSERT INTO @ItemsHistory SELECT 1, 1, 301, NULL, GETDATE() 
INSERT INTO @ItemsHistory SELECT 2, 2, 301, NULL, GETDATE() 
INSERT INTO @ItemsHistory SELECT 3, 3, 301, 'Hello Dear', DATEADD(DD, 1, GETDATE()) 
INSERT INTO @ItemsHistory SELECT 4, 4, 301, 'Dimd you get my msg?', DATEADD(DD, 2, GETDATE()) 
INSERT INTO @ItemsHistory SELECT 5, 5, 302, NULL, GETDATE() 
INSERT INTO @ItemsHistory SELECT 6, 6, 302, NULL, DATEADD(DD, 1, GETDATE()) 
INSERT INTO @ItemsHistory SELECT 7, 7, 302, 'How are you doing?', DATEADD(DD, 3, GETDATE()) 
INSERT INTO @ItemsHistory SELECT 8, 8, 302, 'Your Items are ready', DATEADD(DD, 4, GETDATE()) 

私はPID

に関連するすべての ItemsHistory.NotesHisotry列を持つアイテムテーブルの Items.NotesHistory列を更新するには、実は私は、1つの文字列にアイテムテーブルの Notes列とItemsHistoryテーブルの NotsHistory列内のすべてのデータをCONCATしたいです

カーソルを使用せずにこれを手伝ってもらえますか?私はCTEがこれを行うことができるようにSQL Server 2008を使用していますが、私はこれをどのように達成できるのか分かりません。結果の文字列が一部後

<b>Items.CreaedDate - Items.StaffName: <b/> Items.Notes <br/><b>ItemsHisotryCreatedDate - ItemsHistory.StaffName <b> ItemsHistory.NotesHistory 

を次のようにする必要があり

は、各レコードにItemsHistoryテーブルから追加されますユニークな「PIdを」

<br/><b>ItemsHisotryCreatedDate - ItemsHistory.StaffName <b> ItemsHistory.NotesHistory 

感謝のために追加。

答えて

1

どう

;WITH Vals AS (
     SELECT PIdFK, 
       Notes, 
       ItemIdFK 
     FROM @ItemsHistory ih INNER JOIN 
       @Items i ON ih.ItemIdFK = i.ItemId 
     WHERE Notes IS NOT NULL 
) 
SELECT 
     v.PIdFK, 
     STUFF( 
       (SELECT 
        ', ' + v2.Notes 
        FROM Vals v2 
        WHERE v.PIdFK=v2.PIdFK 
        ORDER BY v2.ItemIdFK 
        FOR XML PATH(''), TYPE 
       ).value('.','varchar(max)') 
       ,1,2, '' 
     ) AS Notes 
FROM Vals v 
GROUP BY v.PIdFK 
+0

ありがとうございます、結果は私が見ているものではありません。 '101 \t私のメッセージはありますか?こんにちは親愛なる、どうやっていますか?あなたの商品は準備完了です。 '102 \tあなたは私のメッセージを受け取りましたか?こんにちは親愛なる、どうやっていますか?あなたの商品は準備ができています。 結果は であるはずです。101こんにちは。私のメッセージを受け取ったのですか? 102どうやって準備していますか? フォーマットは残念です。 – Kashif

+0

申し訳ありませんが、私の悪い、もう一度やり直してください。 –

4

以下のような方法でループなしで連結することができます。ちょうどあなた自身のクエリで追加の/ etc、必要に応じて加入:

DECLARE @s varchar(max) = '' 

SELECT @s = @s + '<br/><b>' + CONVERT(varchar(10), i.CreatedDate, 101) + '</b>' + ISNULL(i.Notes, '') 
FROM @Items i 

SELECT @s 

が、これをしない(あなたはそこにはNULL sがそこにないことを確認する必要があります)!

データベースがではない htmlを構築する場所。少なくとも、XSRFの脆弱性に対してはと大いに開きます。 UIレイヤーでこれを行い、使用しているプラ​​ットフォームによって提供されるhtmlエンコーディング関数を適切に使用します。盲目的に文字列をhtmlとして連結することは、ユーザーの文字列を(パラメータを使用する代わりに)TSQLに盲目的に連結することとほぼ同じです。最高でも書式設定はボルケージされます(<などの正しい処理はありません)。最悪の場合、ユーザーは攻撃の直接の危険にさらされます。

+0

おかげでマルク、および 'XSRFの脆弱性' の提案をお寄せいただきありがとうございますようなものについて。実際に私はUIでこれをやっていますが、私はdbデザインを変更してItemsテーブルを更新する必要があります。それで私はただスクリプトを実行して列を更新したいだけです。助けてくれてありがとう。 – Kashif

+0

XML形式でこれを行うことができるかどうかを知っていますか? –

+0

@pstはxhtmlで、htmlではなく.... *おそらく*。それはシナリオに大きく左右されます。フリーフローティングの「
」は痛みを伴う可能性があります。 –

関連する問題