2011-11-14 43 views
0

我嘗試通過連接來自另一個表的行來更新臨時表中的列。T-SQL連接來自行的字符串

看看這個:

DECLARE @Test VARCHAR(MAX); 

CREATE TABLE #Test 
(
    EmployeeId INT 
    ,Html VARCHAR(MAX) 
); 

CREATE TABLE #EmployeeItems 
(
    EmployeeId INT 
    ,ItemNo INT 
); 

INSERT INTO #EmployeeItems (EmployeeId, ItemNo) 
VALUES 
    (1, 1) 
    ,(1, 2); 

INSERT INTO #Test (EmployeeId, Html) VALUES (1, '<div class="first">'); 
SET @Test = '<div class="first">'; 

UPDATE T SET Html += '<div class="second">' + CAST(E.ItemNo AS VARCHAR) + '</div>' 
FROM #Test AS T 
    JOIN #EmployeeItems AS E ON T.EmployeeId = E.EmployeeId; 

SELECT @Test += '<div class="second">' + CAST(E.ItemNo AS VARCHAR) + '</div>' 
FROM #Test AS T 
JOIN #EmployeeItems AS E ON T.EmployeeId = E.EmployeeId; 

UPDATE #Test SET Html += '</div>'; 
SET @Test += '</div>'; 

SELECT Html FROM #Test; 
SELECT @Test; 

DROP TABLE #Test; 
DROP TABLE #EmployeeItems; 

在#TEST表中的列包含:<div class="first"><div class="second">1</div></div>

而@測試變量包含:<div class="first"><div class="second">1</div><div class="second">2</div></div>

這是爲什麼?它有什麼不同?我想我會得到相同的結果,但在表格的情況下,它只連接一行,第一個。

我該怎麼做,而不是運行遊標更新我的表?

編輯

我原來的問題來自於這樣的事情:

我輸入的數據是

CREATE TABLE #Actions(EmployeeId INT,EmployeeName VARCHAR(100),ActionStart TIME,ActionEnd TIME,Type VARCHAR(10)); 
INSERT INTO #Actions(EmployeeId,EmployeeName,ActionStart,ActionEnd, Type) 
VALUES (1,'Bob','09:00','12:00', 'action'),(1,'Bob','14:30','16:00', 'action'),(1,'Bob','18:00','20:00', 'event'),(2,'Susan','10:00','12:00', 'action'); 

我想這樣

<div class="employee" employeeid="1" employeename="Bob"> 
    <div class="action" start="09:00" end="12:00" type="action"></div> 
    <div class="action" start="14:30" end="16:00" type="action"></div> 
    <div class="action" start="18:00" end="20:00" type="event"></div> 
</div> 
<div class="employee" employeeid="2" employeename="Susan"> 
    <div class="action" start="10:00" end="12:00" type="action"></div> 
</div> 

如同第一輸出例如這是一個簡化的例子例。但是如果我解決了一個案例,我可以解決我的問題。你如何用FOR XML子句來做到這一點?

+2

雖然可以,不要在TSQL生成html。你可以做的是查詢'FOR XML'並使用xsl來轉換結果。 (例如,你不應該對你的數據進行html編碼嗎?) –

+0

好的。我編輯了一下我的問題,你能否給我一些建議? – John

回答

0

把變量連接想象成一個怪癖;它是獲取代碼中使用了很多:)如果你想繼續使用它不支持的行爲,您可以修改您的UPDATE語句,像這樣:

UPDATE t 
SET HTML = @Test 
FROM #test t 

的另一種方法是使用FOR XML語法來連接

CREATE TABLE #Test 
    (
     EmployeeId INT 
    , Html VARCHAR(MAX) 
    ) ; 
CREATE TABLE #EmployeeItems 
    (
     EmployeeId INT 
    , ItemNo INT 
    ) ; 
INSERT INTO #EmployeeItems 
     (EmployeeId, ItemNo) 
VALUES (1, 1)  , 
     (1, 2) ; 
INSERT INTO #Test 
     (EmployeeId, Html) 
VALUES (1, '<div class="first">') ; 

UPDATE #Test 
SET  HTML+= REPLACE(REPLACE((SELECT '|div class="second"|' 
             + CAST(E.ItemNo AS VARCHAR) + '|/div|' 
           FROM #Test AS T 
             JOIN #EmployeeItems AS E ON T.EmployeeId = E.EmployeeId 
           FOR 
           XML PATH('') 
           ), '|div class="second"|', 
           '<div class="second">'), '|/div|', '</div>')  
UPDATE #Test 
SET  Html += '</div>' ; 

SELECT Html 
FROM #Test ; 


DROP TABLE #Test ; 
DROP TABLE #EmployeeItems ; 

或者(也許最好),直接建立你的XML文件。

SELECT 'first' AS "div/@class" 
     , 'second' AS "div/div/@class" 
     , e.ItemNo AS "div/div" 
FROM #EmployeeItems e 
FOR  XML PATH('') 

的編輯問題的更多答案:

BEGIN TRAN 


CREATE TABLE #Actions 
    (
     EmployeeId INT 
    , EmployeeName VARCHAR(100) 
    , ActionStart TIME 
    , ActionEnd TIME 
    , Type VARCHAR(10) 
    ) ; 
INSERT INTO #Actions 
     (EmployeeId, EmployeeName, ActionStart, ActionEnd, Type) 
VALUES (1, 'Bob', '09:00', '12:00', 'action'), 
     (1, 'Bob', '14:30', '16:00', 'action'), 
     (1, 'Bob', '18:00', '20:00', 'event'), 
     (2, 'Susan', '10:00', '12:00', 'action') ; 

; 
WITH CTE 
      AS (SELECT DISTINCT 
         EmployeeID 
         , EmployeeName 
       FROM  #actions 
      ) 
    SELECT 'employee' AS "@class" 
      , employeeid AS "@employeeid" 
      , employeename AS "@employeename" 
      , (SELECT 'action' AS "@class" 
         , ActionStart AS "@start" 
         , ActionEnd AS "@end" 
         , Type AS "@type" 
       FROM  #Actions a2 
       WHERE  a2.EmployeeId = a.EmployeeID 
      FOR 
       XML PATH('div') 
       , TYPE 
      ) 
    FROM cte a 
FOR  XML PATH('div') 


ROLLBACK TRAN  
+0

第二個選項實際上回答我的問題,所以在這裏你去。但請看看我編輯的問題,也許我過分了解我的解決方案。對我原來的問題可能有一個更簡單的答案。 – John

0

爲測試表,更新的每一行完成的,因此,如果您選擇表中的所有行,你會得到兩行:

<div class="first"><div class="second">1</div></div> 
<div class="first"><div class="second">2</div></div> 

在第二種情況下,將增加'<div class="second">' + CAST(E.ItemNo AS VARCHAR) + '</div>'與表中的行數一樣多。由於你有兩行,它會將兩個div添加到變量中。

如果您希望表中的每一行具有值@Test,則不需要光標。只需更新表格即可獲得值@Test

相關問題