我正在尝试将以下MS SQL Server过程迁移到PostgreSQL函数。
CREATE PROCEDURE [dbo].[GMC]
AS
BEGIN
DECLARE @LID VARCHAR(3);
DECLARE @xml XML = '<XMLProf><CID>840</CID><MD>101113</MD></XMLProf>';
SELECT @LID = Pay.b.value('.','Varchar(3)')
FROM @xml.nodes('/XMLProf/CID') as Pay(b)
SELECT 'Return Value' = @LID
END
我已尝试转换为以下内容,但它不起作用。
CREATE OR REPLACE FUNCTION dbo.GMC()
RETURNS void
AS
$BODY$
DECLARE
LID VARCHAR(3);
bxml XML = '<XMLProf><CID>840</CID><MD>101113</MD></XMLProf>';
BEGIN
SELECT LID = Pay.b.value('.','Varchar(3)')
FROM XMLTABLE('/XMLProf/CID' PASSING bxml) as Pay(b)
SELECT 'Return Value' = LID
end;
$BODY$
LANGUAGE plpgsql;
编辑: 我期望的结果是“ 840”
我得到的错误是语法错误:
ERROR: syntax error at or near ")"
LINE 12: FROM XMLTABLE('/XMLProf/CID' PASSING bxml) as Pay(b)
有人可以告诉我如何做到这一点。任何帮助都非常感谢。
答案 0 :(得分:1)
如果要从函数返回某些内容,则不能使用returns void
。因为XML是字符数据,所以returns text
更有意义。
由于您只想返回一个值,因此实际上不需要xmltable()
。而且您也不需要PL / pgSQL:
CREATE OR REPLACE FUNCTION dbo.gmc()
RETURNS text
AS
$BODY$
select (xpath('/XMLProf/CID/text()',
'<XMLProf><CID>840</CID><MD>101113</MD></XMLProf>'::xml))[1]::text;
$BODY$
LANGUAGE sql;
xpath()
返回一个包含所有匹配项的数组,这就是为什么需要[1]
来挑选第一个匹配项的原因。
假设您确实想将XML传递给该函数,则可以使用以下方法:
CREATE OR REPLACE FUNCTION dbo.gmc(p_xml xml)
RETURNS text
AS
$BODY$
select (xpath('/XMLProf/CID/text()', p_xml))[1]::text;
$BODY$
LANGUAGE sql;
答案 1 :(得分:1)
如果将响应元素基于XMLProf
的内部节点的字符串大小,则可能要看一下XPATH
和UNNEST
。
CREATE OR REPLACE FUNCTION gmc() RETURNS text
AS $BODY$
WITH j AS (
SELECT
UNNEST(XPATH('//XMLProf/node()',
'<XMLProf><CID>840</CID><MD>101113</MD></XMLProf>'::XML)) AS rawxml
) SELECT (XPATH('//text()',j.rawxml))[1]::TEXT FROM j
WHERE CHAR_LENGTH((XPATH('//text()',j.rawxml))[1]::TEXT) = 3
$BODY$
LANGUAGE sql;
正在测试..
db=# SELECT * FROM gmc();
gmc
-----
840
(1 Zeile)
如果您确切地知道在哪里查找并且字符串长度无关紧要,请摆脱UNNEST
并使用 @a_horse_with_no_name 指出的XPATH /XMLProf/CID/text()
。