DO(7)
π« DO(7) β bestie, let me introduce you to DO π«
Okay so picture this: you're in PostgreSQL, you've got a PostgreSQL 13.23 manual page open, and you stumble onto DO. And I'm like, bestie, this is literally the "execute an anonymous code block" moment, no cap. It's giving main character energy for one-off scripts. Periodt. π
β¨ SYNOPSIS β¨
So the whole vibe is just:
DO [ LANGUAGE lang_name ] code
That's it. That's the whole thing. Slay. π
πΈ DESCRIPTION πΈ
Okay so DO executes an anonymous code block. Think of it as a transient anonymous function in a procedural language β like a function that's just passing through, no strings attached, no name, no permanent record. It's the guest star of your SQL session. π¦
The way it works is the code block gets treated as though it were the body of a function that has no parameters and returns void. And it's parsed and executed a single time. Not looped, not saved, not re-run. One and done. Iconic behavior honestly. π
Also, the optional LANGUAGE clause is super chill β you can write it either before or after the code block. Your choice, bestie. We love flexibility. π
π§ PARAMETERS π§
Okay so there are literally two parameters and I'm obsessed with how simple this is:
codeβ The procedural language code to be executed. And this part is important, bestie: it must be specified as a string literal, just like inCREATE FUNCTION. And lowkey, using a dollar-quoted literal is recommended. Trust me on this one, iykyk. π―lang_nameβ The name of the procedural language the code is written in. And if you just... don't feel like specifying it? The default isplpgsql. Slay. Defaults are a gift. π
π₯ NOTES π₯
Okay so there's some stuff you need to know before you go off and DO your thing:
- The procedural language you're trying to use? Yeah, it must already have been installed into the current database by way of
CREATE EXTENSION. And here's the thing:plpgsqlis installed by default, but other languages are not. So don't come for me when your fancy language isn't there yet. π - The user must have
USAGEprivilege for the procedural language. Or, if the language is untrusted, you must be a superuser. And this is literally the same privilege requirement as for creating a function in the language. Same energy, same rules. π
Ok but this next one is highkey important, so listen up: ifDOis executed in a transaction block, then the procedure code cannot execute transaction control statements. Those are only allowed ifDOis executed in its own transaction. No cap. Don't test it. Or do, but like, know what you're doing. π
π EXAMPLES π
Okay so here's a genuinely iconic example β granting all privileges on all views in schema public to role 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$$;
Like, look at that dollar-quoting. Look at that loop. It ate and left no crumbs. πβ¨
π«Ά COMPATIBILITY π«Ά
I have to tell you the truth bestie: there is no DO statement in the SQL standard. So like... it's a PostgreSQL thing. Fr fr. π
β SEE ALSO β
CREATE LANGUAGE (CREATE_LANGUAGE(7))β go check that one out too, it's the whole origin story for how your procedural language gets installed. β¨
And that's the whole page, bestie! Written for PostgreSQL 13.23, dated 2025 β catch you on the next manpage. Mwah! ππ
π
π¦ where this page comes from
- opensuse-leap 16.0: postgresql13 13.23-160000.1.1 Β· PostgreSQL
- opensuse-leap 16.0: postgresql13 13.23-160000.1.1 Β· PostgreSQL
- opensuse-leap 16.0: postgresql13 13.23-160000.1.1 Β· PostgreSQL
- opensuse-leap 16.0: postgresql13 13.23-160000.1.1 Β· PostgreSQL
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms