gpt4 book ai didi

mysql - postgres - 修改 xml(MySql UpdateXml 替代)

转载 作者:行者123 更新时间:2023-11-29 03:37:23 24 4
gpt4 key购买 nike

我正在将 mysql 数据库迁移到 postgres,但遇到了有关一些基本 xml 功能的障碍。在 MySql 中,我有存储过程可以替换 xml 文档中的节点,但在 postgres 中找不到任何方法来这样做。

这是我从 mysql 中存储的过程:

CREATE DEFINER=`root`@`localhost` PROCEDURE `SP_UpdateExamFilesXmlNode`(examFileId int, xPathExpression varchar(128), xmlNode longtext)
BEGIN
DECLARE xmlData longtext;
DECLARE newXmlData longtext;
DECLARE xmlNodeCount int;
SET xmlData = NULL;
SELECT xml_data INTO xmlData FROM sonixhub.exam_files WHERE id = examFileId;

IF xmlData IS NOT NULL THEN
-- check if the node already exists and if it does then simply update it
SET xmlNodeCount = ExtractValue(xmlData, CONCAT('count(',xPathExpression,')'));
IF xmlNodeCount > 0 THEN
SET newXmlData = UpdateXML(xmlData, xPathExpression, xmlNode);
-- if node doesn't exist then we have to add it manually
ELSE
SET newXmlData = REPLACE(xmlData, '</ImageXmlData>', CONCAT(xmlNode, '</ImageXmlData>'));
END IF;
UPDATE sonixhub.exam_files SET xml_data = newXmlData WHERE id = examFileId;
ELSE
-- there is no xml found so create xml from scratch and insert the node
SET xmlData = CONCAT('<ImageXmlData>',xmlNode,'</ImageXmlData>');
UPDATE sonixhub.exam_files SET xml_data = xmlData WHERE id = examFileId;
END IF;
END

有什么方法可以在 postgres 函数中复制此功能,而不是将逻辑移至应用程序本身?

编辑 - 找到我的问题的解决方案

我找到了一个混合使用 postgres xml 和字符串格式化函数的解决方案。

examFileId 用于查找要用 xml 更新的行,用你的表信息更改代码 在我的例子中是硬编码的根节点,但您可以将其更改为您喜欢的任何内容。

调用函数的方式如下:

-- this adds <DicomTags> node to your xml value in the table, if <DicomTags> already exists then it's replaced by the one passed in
select update_exam_files_xml_node(1, '/ImageXmlData/DicomTags', '<DicomTags><DicomTag>xxx</DicomTag></DicomTags>');

-- this adds <Settings> node to your xml value in the table, if <Settings> already exists then it's replaced by the one passed in
select update_exam_files_xml_node(1, '/ImageXmlData/Settings', '<Settings>asdf</Settings>');


CREATE OR REPLACE FUNCTION update_exam_files_xml_node(examFileId int, xPathExpression text, xmlNode text)
RETURNS void AS
$BODY$
DECLARE xmlData xml;
DECLARE newXmlData xml;
DECLARE xmlNodeCount int;
DECLARE replaceTag text;
BEGIN
SELECT xml_data INTO xmlData FROM exam_files WHERE id = examFileId;

IF xml_is_well_formed(xmlNode) = false THEN
PERFORM add_error_log('update_exam_files_xml_node', 'xmlNode is not well formed xml');
RETURN;
END IF;

IF xmlData IS NOT NULL THEN
-- check if the node already exists and if it does then simply update it
IF xmlexists(xPathExpression PASSING BY REF xml(xmlData)) = true THEN
-- get the node name
replaceTag := regexp_replace(xPathExpression, '/.*/', '');

-- replace the existing node with the newly passed in node
newXmlData := xml(regexp_replace(xmlData::text, '<'||replaceTag||'>.*</'||replaceTag||'>', xmlNode));

-- if node doesn't exist then we have to add it manually
ELSE
newXmlData := xml(REPLACE(xmlData::text, '</ImageXmlData>', xmlNode||'</ImageXmlData>'));
END IF;
UPDATE exam_files SET xml_data = newXmlData WHERE id = examFileId;
ELSE
-- there is no xml found so create xml from scratch and insert the node
xmlData := '<ImageXmlData>'||xmlNode||'</ImageXmlData>';
UPDATE exam_files SET xml_data = xmlData WHERE id = examFileId;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

最佳答案

很高兴您找到了解决方案。老实说,由于与语言层次结构相关的问题,在 SGML 中可靠地使用字符串格式化函数往往有点困难。 IE。正则表达式对其功能有严格限制。

更好的解决方案可能是转向完全不同的方向,用 PL/PerlU 或 PL/Python 编写您的函数,并使用这些语言的现有 XML 处理功能。这可能会为您提供更好、更可靠的解决方案。

关于mysql - postgres - 修改 xml(MySql UpdateXml 替代),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19376432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com