PostgreSQL:将ms sql xml查询迁移到postgresql查询

时间:2019-11-18 12:51:57

标签: sql xml postgresql

我正在尝试将以下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)

有人可以告诉我如何做到这一点。任何帮助都非常感谢。

2 个答案:

答案 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的内部节点的字符串大小,则可能要看一下XPATHUNNEST

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()