format în PostgreSQL

Funcții pentru text PostgreSQL 9.1+

Construiește un text dintr-un șablon cu %s, %I și %L. Este modul sigur de a crea SQL dinamic în PL/pgSQL.

Sintaxă SQL
format(sablon, arg1, arg2, ...)
-- %s = text, %I = identificator SQL, %L = literal SQL, %% = semnul %

Ce face format

format seamănă cu sprintf din alte limbaje. %s pune valoarea ca text, %I o pune ca identificator SQL (nume de tabel sau coloană, cu ghilimele duble dacă e nevoie), iar %L o pune ca valoare SQL, cu apostrofuri și caracterele speciale dublate.

%I și %L sunt esențiale când construiești comenzi SQL cu EXECUTE în PL/pgSQL: previn erorile și injecțiile SQL când numele sau valorile vin din date.

Argumentele se pot refolosi după poziție (%1$s), iar lățimea se poate fixa (%-10s aliniază la stânga pe 10 caractere).

Parametri

Parametru Descriere
%s Valoarea ca text simplu; NULL devine text gol.
%I Identificator SQL, citat cu ghilimele duble dacă are majuscule, spații sau e cuvânt rezervat.
%L Literal SQL între apostrofuri; NULL devine NULL fără apostrofuri.
%1$s, %-10s Poziția argumentului, respectiv lățimea și alinierea.

Ce returnează

Un text.

Exemple

Exemplul 1: Mesaje cu valori

SELECT format('Bună, %s! Comanda #%s costă %s lei.', 'Ana', 1042, 149.90) AS mesaj;

Rezultat în psql

                   mesaj                    
--------------------------------------------
 Bună, Ana! Comanda #1042 costă 149.90 lei.
(1 row)

Exemplul 2: Ce fac %I și %L

SELECT format('SELECT * FROM %I WHERE nume = %L', 'Clienți Iași', 'O''Brien') AS sql_sigur,
       format('%L', NULL) AS valoare_nula;

Rezultat în psql

                      sql_sigur                       | valoare_nula 
------------------------------------------------------+--------------
 SELECT * FROM "Clienți Iași" WHERE nume = 'O''Brien' | NULL
(1 row)

Exemplul 3: SQL dinamic într-un bloc DO

Numărăm rândurile din mai multe tabele; numele tabelelor vin din catalog, deci le citează %I.

DO $$
DECLARE
    t text;
    n bigint;
BEGIN
    FOREACH t IN ARRAY ARRAY['clienti', 'comenzi'] LOOP
        EXECUTE format('SELECT count(*) FROM %I', t) INTO n;
        RAISE NOTICE '%: % rânduri', t, n;
    END LOOP;
END
$$;

Rezultat în psql

NOTICE:  clienti: 250 rânduri
NOTICE:  comenzi: 1312 rânduri
DO

Greșeli frecvente

  • Construiești SQL dinamic cu || și valori venite de la utilizator: '... WHERE nume = ''' || nume || ''''. Un apostrof în nume strică interogarea sau permite injecție SQL. Folosește %L sau EXECUTE ... USING.
  • Folosești %s pentru nume de tabele: un nume cu majuscule sau spații nu mai funcționează. Pentru identificatori folosește %I.

Comenzi înrudite

  • concat, concat_ws și ||: Lipesc mai multe texte într-unul. || dă NULL dacă o parte este NULL, concat și concat_ws ignoră valorile NULL.
  • DO (bloc anonim): Rulează o singură dată un bloc de cod PL/pgSQL, fără să creeze o funcție. Util pentru scripturi de întreținere și migrări.
  • CREATE FUNCTION (LANGUAGE plpgsql): Creează o funcție în PL/pgSQL, limbajul procedural al PostgreSQL: variabile, IF, bucle, tratarea erorilor.
  • RAISE și EXCEPTION (PL/pgSQL): RAISE afișează mesaje sau oprește codul cu o eroare; blocul EXCEPTION prinde erorile și le tratează.