我有一个包含两个NUMERIC类型字段和一个XML类型字段的表。这是一个粗略的样本:
CREATE TABLE books (
ID INT NOT NULL,
price NUMERIC(4,2),
discount NUMERIC(2,2),
book XML
);
XML值看起来像是
<?xml version="1.0" encoding="UTF-8"?>
<book>
<title>Harry Potter</title>
<author>J K Rowling</author>
<Store>
<Name>Burke and Burkins</Name>
<Address>Some St, Somewhere, Some City</Address>
</Store>
</book>
现在我的问题是,使用xml.modify()
,我如何在Store下添加两个xpath,价格和折扣包含来自books.price
和books.discount
的值?
<?xml version="1.0" encoding="UTF-8"?>
<book>
<title>Harry Potter</title>
<author>J K Rowling</author>
<Store>
<Name>Burke and Burkins</Name>
<Address>Some St, Somewhere, Some City</Address>
<Price>value from books.price from the same row</Price>
<Discount>value from books.discount from the same row</Discount>
</Store>
</book>
这是一个粗略的例子,所以请不要担心XML数据来自何处。让我们说book book列已经存在XML数据。
我知道如何使用静态值更新表格,
UPDATE books
SET book.modify('insert <Price>10.99</Price><Discount>20.00</Discount> after (/book/Store/Address)[1]')
此处不考虑性能。
答案 0 :(得分:4)
在一个陈述中不可能进行两次修改。
在这种情况下,您可以先将两个值组合起来,然后立即插入它们来解决这个问题。
我使用可更新的CTE 来实现这一目标:
CREATE TABLE books (
ID INT NOT NULL,
price NUMERIC(4,2),
discount NUMERIC(2,2),
book XML
);
- 在表格中填入数据
INSERT INTO books VALUES(1,10.5,.5,
'<book>
<title>Harry Potter</title>
<author>J K Rowling</author>
<Store>
<Name>Burke and Burkins</Name>
<Address>Some St, Somewhere, Some City</Address>
</Store>
</book>');
- 这是实际查询
WITH CTE AS
(
SELECT *
,(SELECT price AS Price,discount AS Discount FOR XML PATH(''),TYPE) AS XmlNode
FROM books
)
UPDATE CTE SET book.modify('insert sql:column("XmlNode") after (/book/Store/Address)[1]');
- 检查结果
SELECT *
FROM books;
- 清理(仔细查看真实日期!)
GO
--DROP TABLE books;
你的XML专栏,如果它真的是XML,肯定会! - 不包含以<?xml version="1.0" encoding="UTF-8"?>
开头的XML。内部编码始终是unicode(ucs-2
,几乎为utf-16
),并且无法更改此内容。如果您传递声明,则会被忽略或者您会收到错误。
另一种方法是先读取XML的值,然后重建它:
WITH CTE AS
(
SELECT *
,(SELECT b.value('title[1]','nvarchar(max)') AS [title]
,b.value('author[1]','nvarchar(max)') AS [author]
,b.value('(Store/Name)[1]','nvarchar(max)') AS [Store/Name]
,b.value('(Store/Address)[1]','nvarchar(max)') AS [Store/Address]
,price AS [Store/Price]
,discount AS [Store/Discount]
FROM book.nodes('book') AS A(b)
FOR XML PATH('book'),TYPE
) AS bookNew
FROM books
)
UPDATE CTE SET book=bookNew;