Sql server 2005 使用XQuery modify修复SQL更新以处理SQL 2005

Sql server 2005 使用XQuery modify修复SQL更新以处理SQL 2005,sql-server-2005,xquery,xquery-sql,xml-dml,xquery-update,Sql Server 2005,Xquery,Xquery Sql,Xml Dml,Xquery Update,我试图将一组字段从一个表移动到一个包含在同一个表中的xml blob中。成功后,我将从表中删除该列。下面是一个非常简单的版本,没有我提出的drop列,它在SQL 2008上运行良好-但是我发现这在SQL 2005上不起作用。我得到错误XQuery:XQuery中不支持SQL类型“datetime”。由于字段的数量,我实际上是通过在SP中执行构造的SQL语句来实现这一点的,但为了简单起见,我在示例中使用了普通语句: if OBJECT_ID('tempdb..#Case') is not null

我试图将一组字段从一个表移动到一个包含在同一个表中的xml blob中。成功后,我将从表中删除该列。下面是一个非常简单的版本,没有我提出的drop列,它在SQL 2008上运行良好-但是我发现这在SQL 2005上不起作用。我得到错误XQuery:XQuery中不支持SQL类型“datetime”。由于字段的数量,我实际上是通过在SP中执行构造的SQL语句来实现这一点的,但为了简单起见,我在示例中使用了普通语句:

if OBJECT_ID('tempdb..#Case') is not null
 DROP Table #Case;

CREATE TABLE #Case 
( 
    id INT, 
    DecisionDate DateTime,
    CaseBlob xml
)

INSERT INTO #Case Values(1, '10-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>')
INSERT INTO #Case Values(2, '20-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>')
INSERT INTO #Case Values(3, null, '<CaseBlob></CaseBlob>')
INSERT INTO #Case Values(4, '21-OCT-2011 10:10:00', '<CaseBlob></CaseBlob>')
INSERT INTO #Case Values(5, null, '<CaseBlob></CaseBlob>')


UPDATE #Case
   SET CaseBlob.modify('insert <DecisionDate>{sql:column("#Case.DecisionDate")}</DecisionDate>
   as last into (/CaseBlob)[1]')
   WHERE #Case.DecisionDate is not null
   AND CaseBlob.exist('(/CaseBlob/DecisionDate)') = 0

SELECT * FROM #CASE
我已经尝试过用xs:stringsql:columnCase.DecisionDate包装sql:columnCase.DecisionDate,但这似乎没有帮助。@marc_s指出,在.modifyinsert语句中使用sql:column是在sql 2008之前才引入的,所以我认为这是一种误导

由于这是一个一次性的迁移脚本,只需要运行一次,我是否认为我应该从设置方法转移到过程循环方法,以满足我的需求。由于服务器版本的限制以及我试图实现的目标,这听起来像是正确的方法吗?非常感谢您的指点。

第一部分:

您可以使用CTE查询使用日期时间样式转换为字符串的日期部分

;with C as
(
  select CaseBlob,
         convert(varchar(23), DecisionDate, 126) as DecisionDate
  from #Case
  where DecisionDate is not null and
        CaseBlob.exist('(/CaseBlob/DecisionDate)') = 0
)
update C
set CaseBlob.modify('insert <DecisionDate>{sql:column("DecisionDate")}</DecisionDate>
                     as last into (/CaseBlob)[1]')
与update语句相比,使用该语句的输出略有不同。如果毫秒数为.000,它将省略毫秒数。如果它们实际上有一个值,它将被包括在内,这样您就不会丢失任何数据。只是不同而已

第二部分:

我真的不太明白它是如何与上面的连接到一起的,因此无法给出一些示例代码。但是,如果需要从其他表中添加更多内容,可以在CTE中加入这些表,并将列作为CTE的输出,用于modify语句插入值。

第一部分:

您可以使用CTE查询使用日期时间样式转换为字符串的日期部分

;with C as
(
  select CaseBlob,
         convert(varchar(23), DecisionDate, 126) as DecisionDate
  from #Case
  where DecisionDate is not null and
        CaseBlob.exist('(/CaseBlob/DecisionDate)') = 0
)
update C
set CaseBlob.modify('insert <DecisionDate>{sql:column("DecisionDate")}</DecisionDate>
                     as last into (/CaseBlob)[1]')
与update语句相比,使用该语句的输出略有不同。如果毫秒数为.000,它将省略毫秒数。如果它们实际上有一个值,它将被包括在内,这样您就不会丢失任何数据。只是不同而已

第二部分:


我真的不太明白它是如何与上面的连接到一起的,因此无法给出一些示例代码。但是,如果您需要从其他表中添加更多内容,您可以在CTE中加入这些表,并将列作为CTE的输出,用于modify语句插入值。

@Mikeal Eriksson:谢谢,我将尝试一下-我还删除了第二个不相关的部分,米克尔·埃里克森:谢谢你,我会试试看——我还去掉了第二个不相关的部分,当时我脑子里想的太多了。