如何使用Oracle在SQL/XML中的XML类型列中插入XML行?
我试图在OracleSQLDeveloper中编写一个SQL/XML查询来更新数据库表中的某一行。数据库具有以下结构: 属性“Translations”是XML类型。例如,我有一本书名为“Encore une fois”,原文为“法语”,ID为“11”。本书有以下两个版本:如何使用Oracle在SQL/XML中的XML类型列中插入XML行?,sql,oracle,sql-update,xquery,sqlxml,Sql,Oracle,Sql Update,Xquery,Sqlxml,我试图在OracleSQLDeveloper中编写一个SQL/XML查询来更新数据库表中的某一行。数据库具有以下结构: 属性“Translations”是XML类型。例如,我有一本书名为“Encore une fois”,原文为“法语”,ID为“11”。本书有以下两个版本: ID "17", Year "1997", Price "120", Book "11" Translations: <Translations> <Translati
ID "17", Year "1997", Price "120", Book "11"
Translations: <Translations>
<Translation Language="English" Price="120"/>
<Translation Language="Russian" Price="110"/>
</Translations>
但是我更新了两行而不是一行,因为两个版本都放了它,这是错误的。如何仅在第二版中输入该行?看起来您已经完成了最难的部分-您只需要在UPDATE语句中添加一个条件,指定版本中的一行而不是两行。我建议您使用SELECT语句测试WHERE子句,以确保您得到的是所需的行
SELECT *
FROM BOOKDB.EDITION
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
这将返回当前正在更新的2行,对吗
那么就在那之后
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
你可以加上
AND Edition.ID = '18'
AND Edition.Year = '2001'
,或者您可以添加
AND Edition.ID = '18'
AND Edition.Year = '2001'
如果希望更通用的解决方案始终更新最新版本,可以执行子查询以确保选择的是最新版本:
AND not exists (select 1 from BOOKDB.Edition e
where e.Book = Edition.Book
and e.Year > Edition.Year)
一旦有了WHERE子句来选择所需的行,请将其添加回UPDATE语句:
UPDATE BOOKDB.EDITION
SET Translations = XMLQUERY('copy $res := $t
modify insert node element Translation {attribute Language {"Norwegian"}, attribute Publisher {"KLC"}, attribute Price {200}}
as last into $res/Translations
return $res'
PASSING Translations AS "t" RETURNING CONTENT)
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
AND Edition.ID = '18'
看起来您已经完成了最难的部分-您只需要在UPDATE语句中添加一个条件,该条件在EDITION中指定一行而不是两行。我建议您使用SELECT语句测试WHERE子句,以确保您得到的是所需的行
SELECT *
FROM BOOKDB.EDITION
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
这将返回当前正在更新的2行,对吗
那么就在那之后
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
你可以加上
AND Edition.ID = '18'
AND Edition.Year = '2001'
,或者您可以添加
AND Edition.ID = '18'
AND Edition.Year = '2001'
如果希望更通用的解决方案始终更新最新版本,可以执行子查询以确保选择的是最新版本:
AND not exists (select 1 from BOOKDB.Edition e
where e.Book = Edition.Book
and e.Year > Edition.Year)
一旦有了WHERE子句来选择所需的行,请将其添加回UPDATE语句:
UPDATE BOOKDB.EDITION
SET Translations = XMLQUERY('copy $res := $t
modify insert node element Translation {attribute Language {"Norwegian"}, attribute Publisher {"KLC"}, attribute Price {200}}
as last into $res/Translations
return $res'
PASSING Translations AS "t" RETURNING CONTENT)
WHERE Edition.Book in (SELECT ID FROM BOOKDB.Book WHERE Title = 'Encore une fois')
AND Edition.ID = '18'
如果只想更新second版本,则编写子查询,查找第二个id,并在
in
子句中使用此子查询。我使用id
进行订购,但您也可以使用year
。如果您想在中使用它,请按行数中的顺序使用它
UPDATE EDITION
SET Translations = XMLQUERY('copy $res := $t
modify insert node element Translation {attribute Language {"Norwegian"}, attribute Publisher {"KLC"}, attribute Price {200}}
as last into $res/Translations
return $res'
PASSING Translations AS "t" RETURNING CONTENT)
where (book, id) in (
select book, id
from (
select book.id book, edition.id,
row_number() over (partition by book.id order by edition.id) rn
from book join edition on book.id = edition.book where title = 'Encore une fois')
where rn = 2);
如果只想更新第二版则编写子查询,查找第二个id,并在in
子句中使用此子查询。我使用id
进行订购,但您也可以使用year
。如果您想在中使用它,请按行数中的顺序使用它
UPDATE EDITION
SET Translations = XMLQUERY('copy $res := $t
modify insert node element Translation {attribute Language {"Norwegian"}, attribute Publisher {"KLC"}, attribute Price {200}}
as last into $res/Translations
return $res'
PASSING Translations AS "t" RETURNING CONTENT)
where (book, id) in (
select book, id
from (
select book.id book, edition.id,
row_number() over (partition by book.id order by edition.id) rn
from book join edition on book.id = edition.book where title = 'Encore une fois')
where rn = 2);
谢谢,我刚刚添加了年份约束谢谢,我刚刚添加了年份约束