DO(7)

πŸ“¦ version 13.23, in opensuse-leap 16.0

πŸ’« 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 in CREATE 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 is plpgsql. 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: plpgsql is 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 USAGE privilege 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: if DO is executed in a transaction block, then the procedure code cannot execute transaction control statements. Those are only allowed if DO is 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