开发 PL/pgSQL 的一个好方法是:
用你喜欢的文本编辑器创建函数,然后在另一个窗口中使用
psql 加载并测试这些函数。
如果采用这种方式,建议用 CREATE OR
REPLACE FUNCTION 来书写函数。
这样,重新加载文件即可更新函数定义。例如:
CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$
....
$$ LANGUAGE plpgsql;
在运行 psql 期间, 可以用以下命令加载或重新加载这样的函数定义文件:
\i filename.sql
然后立即发出 SQL 命令来测试该函数。
开发 PL/pgSQL 的另一个好方法是使用 便于过程语言开发的 GUI 数据库访问工具。这类工具的一个例子是 pgAdmin,此外还有其他工具。 这些工具通常提供一些便利特性,例如转义单引号, 以及更轻松地重建和调试函数。
PL/pgSQL 函数的代码在
CREATE FUNCTION 中以字符串字面值的形式给出。
如果你用普通的方式书写这个字符串字面值,即用单引号包围,
那么函数体内部的任何单引号都必须加倍;
同样,任何反斜线也必须加倍(假设使用的是转义字符串语法)。
引号加倍充其量是件繁琐的事,而在更复杂的情况下,
代码可能变得完全难以理解,因为你很容易发现自己需要
六个或更多相邻的引号。建议你改为把函数体写成一个
“美元符引用”的字符串字面值
(见 Section 4.1.2.4)。
在美元符引用方式下,你永远不需要把任何引号加倍,
只需要小心地为你需要的每一层嵌套选择不同的美元符引用定界符。
例如,你可以这样书写 CREATE FUNCTION 命令:
CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$
....
$PROC$ LANGUAGE plpgsql;
在其内部,你可以在 SQL 命令中对简单的字面字符串使用引号,
并用 $$ 来定界你正在作为字符串组装的
SQL 命令片段。如果你需要引用包含 $$ 的文本,
可以使用 $Q$,依此类推。
下表展示了在不使用美元符引用时书写引号必须做的事情。 在把美元符引用出现之前的代码转换成更容易理解的形式时, 它可能有用。
用于开始和结束函数体,例如:
CREATE FUNCTION foo() RETURNS integer AS '
....
' LANGUAGE plpgsql;
在单引号函数体内部的任何位置,引号 必须成对出现。
用于函数体内部的字符串字面值,例如:
a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar'';
在美元符引用方式下,你只需写:
a_output := 'Blah'; SELECT * FROM users WHERE f_name='foobar';
这正是 PL/pgSQL 解析器在两种写法下 所看到的内容。
当你需要函数体内字符串常量中的单个引号时,例如:
a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz''
实际追加到 a_output 的值将是:
AND name LIKE 'foobar' AND xyz。
在美元符引用方式下,你应写成:
a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$
注意,这周围任何美元符引用定界符都不要只写成
$$。
当函数体内字符串中的单个引号紧邻该字符串常量的末尾时,例如:
a_output := a_output || '' AND name LIKE ''''foobar''''''
追加到 a_output 的值将是:
AND name LIKE 'foobar'。
在美元符引用方式下,这变成:
a_output := a_output || $$ AND name LIKE 'foobar'$$
当你想要字符串常量中的两个单引号(这占 8 个引号), 且它们紧邻该字符串常量的末尾(再加 2 个)时。 你可能只有在编写生成其他函数的函数时才需要它, 如 Example 41.10 所示。 例如:
a_output := a_output || '' if v_'' ||
referrer_keys.kind || '' like ''''''''''
|| referrer_keys.key_string || ''''''''''
then return '''''' || referrer_keys.referrer_type
|| ''''''; end if;'';
a_output 的值将是:
if v_... like ''...'' then return ''...''; end if;
在美元符引用方式下,这变成:
a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$
|| referrer_keys.key_string || $$'
then return '$$ || referrer_keys.referrer_type
|| $$'; end if;$$;
这里我们假定只需要把单引号放进
a_output,因为它在被使用之前会再次被引用。
为了帮助用户在简单但常见的问题造成危害之前发现它们,
PL/pgSQL 提供了额外的
检查(checks)。启用后(取决于配置),
它们可用于在函数编译期间发出 WARNING
或 ERROR。收到过 WARNING
的函数可以在不产生进一步消息的情况下执行,
因此建议你在单独的开发环境中进行测试。
建议在开发和/或测试环境中酌情把
plpgsql.extra_warnings 或
plpgsql.extra_errors 设置为
"all"。
这些额外的检查通过配置变量启用:
plpgsql.extra_warnings 对应警告,
plpgsql.extra_errors 对应错误。
两者都可以被设置为以逗号分隔的检查列表、
"none" 或 "all"。
默认值为 "none"。当前可用的检查列表包括:
shadowed_variables #检查某条声明是否遮蔽了先前定义的变量。