37.2. PL/pgSQL 开发技巧 #
开发 PL/pgSQL 的一个好方法是,用你选定的文本编辑器创建函数,同时在另一个窗口用 psql 装载并测试这些函数。如果你这样做,最好用 CREATE OR REPLACE
FUNCTION 编写函数。这样只需重新装载文件即可更新函数定义。例如:
CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS '
....
end;
' LANGUAGE plpgsql;
在运行 psql 期间,可以用
\i filename.sql
装载或重新装载这样的函数定义文件,然后立即发出 SQL 命令来测试该函数。
开发 PL/pgSQL 的另一个好方法是使用便于过程语言开发的 GUI 数据库访问工具。PgAccess 就是这样一个工具的例子,尽管还有其他工具。这类工具通常提供便捷特性,例如转义单引号、让重新创建和调试函数变得更容易。
37.2.1. 引号的处理 #
由于 PL/pgSQL 函数的代码在
CREATE FUNCTION 中是作为字符串字面量指定的,函数体内部的单引号必须通过加倍来转义。这有时会导致相当复杂的代码,尤其是当你在编写一个生成其他函数的函数时,例如第 37.6.4 节中的例子。下表可作为各种情况下所需引号数目的一个概要,或许有用。
- 1 个引号
用于开始和结束函数体,例如:
CREATE FUNCTION foo() RETURNS integer AS '...' LANGUAGE plpgsql;在函数体内的任何位置,引号都必须成对出现。
- 2 个引号
用于函数体内部的字符串字面量,例如:
a_output := ''Blah''; SELECT * FROM users WHERE f_name=''foobar'';
PL/pgSQL 会把第二行看作
SELECT * FROM users WHERE f_name='foobar';
- 4 个引号
当你在函数体内部的字符串常量中需要一个单引号时,例如:
a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz''
实际追加到
a_output的值将是:AND name LIKE 'foobar' AND xyz。- 6 个引号
当函数体内部字符串中的一个单引号与该字符串常量的末尾相邻时,例如:
a_output := a_output || '' AND name LIKE ''''foobar''''''
此时追加到
a_output的值将是:AND name LIKE 'foobar'。- 10 个引号
当你想在字符串常量中得到两个单引号(这需要 8 个引号),并且它们与该字符串常量的末尾相邻(再加 2 个)时。只有当你在编写生成其他函数的函数时才可能需要这样做。例如:
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;
另一种方法是用反斜杠而不是加倍来转义函数体中的引号。用这种方法,你会发现自己在写 \'\' 而不是 '''' 这样的东西。有些人觉得这样更容易跟踪,有些人则不这么认为。