2010-12-15 78 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()) 

我想Concat的在項目表的Notes列和ItemsHistory表NotsHistory列到一個字符串中的所有數據,在-其實我是想與PID

相關的所有 ItemsHistory.NotesHisotry列更新項目表 Items.NotesHistory

您可以不使用遊標來幫助您。我正在使用SQL Server 2008,所以CTE可以做到這一點,但我沒有得到如何實現這一目標。

結果字符串應該像下面

<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 2010-12-15 07:30:17

+0

對不起,我不好,再試一次。 – 2010-12-15 07:34:08

4

你可以通過類似下面的東西連接而不用循環;只需添加在自己的查詢需要/連接等:

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在裏面)

但不這樣做!

該數據庫是不是建立html的地方;並非最不重要的一點,它會使您向巨大地轉變爲XSRF漏洞。我會在UI層執行此操作,以適當地使用您正在使用的任何平臺提供的html編碼函數。盲目連接字符串作爲html幾乎與將用戶字符串盲目連接到TSQL(而不是使用參數)相提並論。最好格式化將被borked(沒有正確處理<等) - 最糟糕的情況是,您的用戶有被直接攻擊的風險。

+0

感謝馬克,並感謝 'XSRF漏洞' 的建議。事實上,我在我的UI中這樣做,但我改變了我的數據庫設計,並需要更新Items表。那就是爲什麼我只想運行腳本並更新列。再次感謝您的幫助。 – Kashif 2010-12-15 07:22:42

+0

知道這是否可以用XML類型來完成? – 2010-12-15 07:41:57

+0

@pst只有當它是xhtml,不是html ....但*可能*。這將取決於情景。而自由浮動的'
'可能是一種痛苦。 – 2010-12-15 07:46:17