反斜杠导致 PostgreSQL 语法错误?

发布于 2025-01-01 08:16:42 字数 763 浏览 0 评论 0原文

我正在 PostgreSQL 的 pgAdminIII 中调试一个 sql 文件,该语句在执行时会产生语法错误:

ERROR:  syntax error at or near "v"
LINE 81384: ...n.oid = c.relnamespace  WHERE     c.relkind IN (\'v\') AND n...

该语句:

CREATE OR REPLACE FUNCTION getnextview()   
RETURNS name AS 
' DECLARE
   my_record RECORD;  viewName name; 
BEGIN
FOR my_record IN
  SELECT c.relname
  FROM pg_catalog.pg_class AS c
  LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
  WHERE c.relkind IN (\'v\')
  AND n.nspname NOT IN (\'pg_catalog\', \'pg_toast\')
  AND pg_catalog.pg_table_is_visible(c.oid)
  LIMIT 1
LOOP
   viewName := my_record.relname;  
END LOOP;
RETURN (viewName);
END; '  LANGUAGE 'plpgsql' VOLATILE;

注意,pg_catalog 和 pg_toast 也会出错。

I am debugging a sql file in PostgreSQL's pgAdminIII, and this statement creates a syntax error when executing:

ERROR:  syntax error at or near "v"
LINE 81384: ...n.oid = c.relnamespace  WHERE     c.relkind IN (\'v\') AND n...

The statement:

CREATE OR REPLACE FUNCTION getnextview()   
RETURNS name AS 
' DECLARE
   my_record RECORD;  viewName name; 
BEGIN
FOR my_record IN
  SELECT c.relname
  FROM pg_catalog.pg_class AS c
  LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
  WHERE c.relkind IN (\'v\')
  AND n.nspname NOT IN (\'pg_catalog\', \'pg_toast\')
  AND pg_catalog.pg_table_is_visible(c.oid)
  LIMIT 1
LOOP
   viewName := my_record.relname;  
END LOOP;
RETURN (viewName);
END; '  LANGUAGE 'plpgsql' VOLATILE;

Note, the pg_catalog and pg_toast also error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

路弥 2025-01-08 08:16:42

因此,完整的陈述确实极大地改变了情况。

您的问题是单引号的嵌套。如果您使用 PostgreSQL 的“美元引用”一切都变得容易多了:

CREATE OR REPLACE FUNCTION getnextview() 
  RETURNS name 
AS 
$body$
DECLARE 
    my_record RECORD; 
    viewName name; 
BEGIN 
    FOR my_record IN 
            SELECT c.relname 
            FROM pg_catalog.pg_class AS c 
              LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace 
            WHERE c.relkind IN ('v') 
              AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
              AND pg_catalog.pg_table_is_visible(c.oid) 
            LIMIT 1 
    LOOP 
        viewName := my_record.relname; 
    END LOOP; 

    RETURN (viewName); 
END; 
$body$
LANGUAGE 'plpgsql' 
VOLATILE;

So the full statement does change the picture substantially.

Your problem is the nesting of single quotes. If you use PostgreSQL's "dollar quoting" everything is a lot easier:

CREATE OR REPLACE FUNCTION getnextview() 
  RETURNS name 
AS 
$body$
DECLARE 
    my_record RECORD; 
    viewName name; 
BEGIN 
    FOR my_record IN 
            SELECT c.relname 
            FROM pg_catalog.pg_class AS c 
              LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace 
            WHERE c.relkind IN ('v') 
              AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
              AND pg_catalog.pg_table_is_visible(c.oid) 
            LIMIT 1 
    LOOP 
        viewName := my_record.relname; 
    END LOOP; 

    RETURN (viewName); 
END; 
$body$
LANGUAGE 'plpgsql' 
VOLATILE;
我ぃ本無心為│何有愛 2025-01-08 08:16:42

这完全一样,只是更简单:

CREATE OR REPLACE FUNCTION getnextview()   
RETURNS name AS 
$BODY$

SELECT c.relname 
FROM   pg_catalog.pg_class c
LEFT   JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  c.relkind = 'v'
AND    n.nspname NOT IN ('pg_catalog', 'pg_toast') 
AND    pg_catalog.pg_table_is_visible(c.oid)
LIMIT  1

$BODY$
   LANGUAGE sql STABLE;

This does the same exactly, just simpler:

CREATE OR REPLACE FUNCTION getnextview()   
RETURNS name AS 
$BODY$

SELECT c.relname 
FROM   pg_catalog.pg_class c
LEFT   JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  c.relkind = 'v'
AND    n.nspname NOT IN ('pg_catalog', 'pg_toast') 
AND    pg_catalog.pg_table_is_visible(c.oid)
LIMIT  1

$BODY$
   LANGUAGE sql STABLE;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文