Project: YugabyteDB (App Definition and Development / Database)
File: cmd_do.md

title: DO statement [YSQL] headerTitle: DO linkTitle: DO description: Describes how to use the DO statement to execute an anonymous PL/pgSQL block statementin other words, a transient anonymous PL/pgSQL procedure. menu: v2.18: identifier: cmd_do parent: statements type: docs Use the `DO` statement to execute an anonymous PL/pgSQL block statementin other words, a transient anonymous PL/pgSQL procedure. The is treated as though it were the body of a procedure with no parameters: Any SQL statement that the block statement encounters is treated in the same way as when it is encountered in a subprogram so that if a `DO` statement is repeatedly executed in the same session, using the textually identical block statement, then the second and subsequent executions of the contained SQL statement benefit from the syntax and semantics analysis that was done when it was first encountered. The grammar allows an optional `LANGUAGE` clause that can be written either before or after the code block. However, the only supported choice is language plpgsql. For example, an attempt to execute a `DO` statement that specified language sql causes the 0A000 run-time error: ```output language "sql" does not support inline code execution ``` See the thread on the email list, {{< tip title="Avoid using the optional 'LANGUAGE' clause in a 'DO' statement." >}} Specifying language plpgsql brings no benefit with respect to omitting the `LANGUAGE` clause altogether. You can assume that all developers know that the only supported implementation language is PL/pgSQL. Yugabyte therefore recommends that you avoid cluttering your code and simply always omit the optional `LANGUAGE` clause. {{< /tip >}} {{< note title="The syntax diagram omits the optional 'LANGUAGE' clause." >}} The syntax diagram respects the advice that the tip Avoid using the optional 'LANGUAGE' clause in a 'DO' statement, above, gives. {{< /note >}} {{%ebnf%}} do {{%/ebnf%}} The procedural language code to be executed, . This must be specified as a string literal, just as in and . Yugabyte recommends that you use dollar-quoting and standardize on, for example, $body$. Specifies the name of the procedural language that the code is written in. The default is

See the tip Avoid using the optional 'LANGUAGE' clause in a 'DO' statement, above. This code is legal. And it runs without error and has the intended effect. ```plpgsql do language plpgsql $body$ begin raise info 'Block statement started at %', tochar((statementtimestamp() at time zone 'UTC'), 'hh24:mi:ss Dy'); end; $body$; ``` And the effect is identical if language plpgsql is omitted. See the section . ```plpgsql do $body$ begin drop schema if exists s cascade; create schema s; create table s.masters( mk serial primary key, mv text not null unique); create table s.details( dk serial primary key, mk int not null references s.masters(mk), dv text not null); end; $body$; ``` Suppose that at the moment the `DO` statement is executed, the schema s already exists but is owned by a user other than what the currentrole built-in function returns (and that this current role is not a superuser). Assume, too, that there is currently no ongoing transaction so that the block statement is executed in single statement automatic transaction mode_ (see the section .) The drop schema if exists s cascade attempt will cause the 42501 error: ```output must be owner of schema s ``` The block will then exit immediately with an unhandled exception and the run-time system will automatically issue an under-the-covers commitwhich will have the same effect, here, as rollback. Compare this behavior with that of encapsulating the same statements in an explicit start transaction; ... commit; encapsulation to use multistatement manual transaction mode: ```plpgsql start transaction; drop schema if exists s cascade; create schema s; create table s.masters( mk serial primary key, mv text not null unique); create table s.details( dk serial primary key, mk int not null references s.masters(mk), dv text not null); commit; ``` Now four errors are reported: first, the 42501 error is reported, just as when the `DO` statement is executed in single statement automatic transaction mode; but then three occurrences of the 25P02 error (current transaction is aborted, commands ignored until end of transaction block) are reported. The `DO` statement approach therefore provides the better encapsulation for the four-statement implementation of the business requirement than does the start transaction; ... commit; approach.