【问题标题】:PostgreSQL: migrating ms sql xml query to postgresql queryPostgreSQL:将 ms sql xml 查询迁移到 postgresql 查询
【发布时间】:2020-03-13 20:20:52
【问题描述】:

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

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

【问题讨论】:

  • 您能否添加您期望的结果以及您可能收到的错误消息?
  • 我已经更新了。请检查
  • 你的 Postgres 版本是多少?
  • 你不能从定义为returns void的函数返回一些东西

标签: sql xml postgresql


【解决方案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;

【讨论】:

  • 您可以在 Postgres 10+ 中使用 XMLTABLE
【解决方案2】:

如果您的响应元素基于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()

【讨论】:

    猜你喜欢
    • 2019-10-16
    • 2021-08-21
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 2021-09-24
    • 2021-12-05
    相关资源
    最近更新 更多