2011-11-14 14 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

相关问题