DO

DO — 执行一个匿名代码块

Synopsis

DO [ (type [, ...]) USING (argument [, ...]) ] [ LANGUAGE lang_name ] code

描述

DO执行一个匿名代码块,或者换句话说 执行一个以一种过程语言编写的瞬时匿名函数。

代码块就好像是一个没有参数并且返回void的函数的函数体。 它会被在一次时间内解析并且执行。

通过使用 USING 子句,代码块被当成是一个带输入输出参数的函数体那样执行,并返回 record。 与 prepareStatement 一起用时,它可以只被解析一次,然后可以多次执行,但 do stmt 的解析花费很小,所以意义不大,故一般只用于 ecpg(Oracle Pro*c兼容) 中。

可选的USING子句可以写在代码块之前或者之后。但 LANGUAGE 只能为 pl/sql。

可选的LANGUAGE子句可以写在代码块之前或者之后。

参数

code

要被执行的过程语言代码。就像在 CREATE FUNCTION中一样,必须把它指定为一个 字符串。推荐使用一个美元引用的文本。

lang_name

编写该代码的过程语言的名称。如果省略,默认为plpgsql

type

参数类型,参数的模式总是输入输出型。

argument

实际用于执行匿名执行块的参数,类似 CALL

注解

要使用的过程语言必须已经用CREATE EXTENSION安装在 当前数据库中。默认已经安装了plpgsql,但是其他语言没有被 安装。

用户必须拥有该过程语言的USAGE特权,如果该语言 是不可信的则必须是一个超级用户。这和创建一个该语言的函数对 特权的要求相同。

如果在事务块中执行DO,过程代码则无法执行事务控制语句。只有在自己的事务中执行DO时,才允许使用事务控制语句。

例子

把模式public中所有视图上的所有特权授予 给角色webuser

DO $$DECLARE r record;
BEGIN
    FOR r IN SELECT table_schema, table_name FROM information_schema.tables
             WHERE table_type = 'VIEW' AND table_schema = 'public'
    LOOP
        EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
    END LOOP;
END$$;

在 LANGUAGE pl/sql 下 通过参数把模式public中所有视图上的所有特权授予 给角色webuser

DO $$DECLARE r record;
BEGIN
    FOR r IN SELECT table_schema, table_name FROM information_schema.tables
             WHERE table_type = $1 AND table_schema = $2
    LOOP
        EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
    END LOOP;
END$$ (text, text) USING ('VIEW', 'public') LANGUAGE plorasql;

在 ecpg(Oracle Pro*c兼容) 中的使用案例,请参见 Section 33.5.4

兼容性

SQL 标准中没有DO语句。