使用 XQuery 修改修复 SQL 更新以在 SQL 2005 上工作

发布于 2024-12-09 04:02:33 字数 1432 浏览 0 评论 0原文

我正在尝试将表中的一堆字段移动到同一个表中包含的 xml blob 中。成功后,我将从表中删除该列。下面是我提出的一个非常简单的版本(没有删除列),这在 SQL 2008 上运行良好 - 但是我发现这在 SQL 2005 上不起作用。我收到错误 XQuery:XQuery 中不支持 SQL 类型“datetime”。 由于字段数量的原因,我实际上是通过在 SP 中执行构造的 SQL 语句来完成此操作的,但为了简单起见,我使用了普通的 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:string(sql:column("#Case.DecisionDate")) 包装 sql:column("#Case.DecisionDate") 但那似乎没有帮助。 @marc_s 指出,直到 SQL 2008 才引入 .modify(insert 语句中使用 sql:column( ) - 所以我认为这是 。

由于这是一个一次性迁移脚本并且只需要运行一次,我是否认为我应该放弃 Set 方法并转向程序循环方法来满足我的要求 听起来正确由于服务器版本的限制以及我想要实现的目标,有什么建议吗?

I'm trying to move a bunch of fields from a table into an xml blob contained within the same table. After this is successful I will be removing the column from the table. A really simple version (without the drop column) of what I've come up with is below, and this works fine on SQL 2008 - however I've discovered that this will not work on SQL 2005. I get the error XQuery: SQL type 'datetime' is not supported in XQuery. I'm actually doing this through the execution of a constructed SQL statement within a SP because of the number of fields, but for simplicity I've used a normal statement in the example:

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

I've tried wrapping the sql:column("#Case.DecisionDate") with xs:string(sql:column("#Case.DecisionDate")) but that doesn't seem to help. It has been pointed out by @marc_s that the use of sql:column( within a .modify(insert statement wasn't introduced until SQL 2008 - so I think this is a red herring.

Due to the fact this is a one off migration script and only requires to be run once, am I thinking that I should move away from the Set methods and move to a procedural looping method to cater for my requirements. Does this sound like the correct approach due to the limitation of server version and what I'm trying to achieve? Any pointers greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

段念尘 2024-12-16 04:02:33

第一部分

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

;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]')

与更新语句相比,使用此方式的输出存在微小差异。如果它们是.000,它将省略毫秒。如果它们确实具有值,则会将其包含在内,这样您就不会丢失任何数据。只是不同而已。

第二部分:

我不太明白这与上面的联系如何足够好,无法为您提供一些示例代码。但是,如果您需要从其他表添加更多内容,您可以联接到 CTE 中的这些表,并将这些列作为 CTE 的输出,以便在插入值的修改语句中使用。

First part:

You can use a CTE to query the date part converted to a string using the date time style 126.

;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]')

There is a tiny difference in the output using this compared to your update statement. It will omit the milliseconds if they are .000. If they actually have a value it will be included so you are not missing any data. It's just different.

Second part:

I don't really understand how this connects to the above well enough to give you some sample code. But if you need to add more stuff from other tables you can join to those tables in the CTE and make the columns as output from the CTE to be used in the modify statement inserting values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文