Non omettere AS
parola chiave per gli alias di colonna
Non esattamente. Esplode perché hai omesso la parola chiave AS
dove non deve essere omesso.
Funziona:
SELECT 'select '
|| string_agg(
case when udt_name in ('varchar', 'text')
then 'left(' || quote_ident(column_name) || ', 65535) AS ' -- !!
|| quote_ident(column_name)
else quote_ident(column_name)
end, ', ' order by ordinal_position)
|| ' from "public"."MyTableName"'
FROM information_schema.columns c
join parse_ident('"public"."MyTableName"') t
on t[1] = table_schema and t[2] = table_name;
Produce:
SELECT id, left(first, 65535) AS first from "public"."MyTableName";
Che a sua volta funziona come previsto.
Il manuale su "Omissione del AS Parola chiave" :
È possibile omettere la parola chiave AS
per gli alias di tabella, ma non per gli alias di colonna.
first
non è una parola riservata
a Postgres. (Un tempo era "riservato" nell'antico standard SQL SQL-92, ma non più nemmeno nell'SQL standard.) È "non riservato" * per essere precisi. Il manuale
:
Omettendo AS
lo rende proprio un tale contesto.
quote_ident()
funziona in modo affidabile. Il manuale:
format()
con lo specificatore %I
fa lo stesso.
Le parole riservate non sono menzionate, ma citate correttamente a prescindere. Per la precisione:tutte le parole chiave contrassegnate da "riservato" o "(non può essere funzione o tipo)" nella colonna "PostgreSQL" di il Parole chiave SQL tabella .
Rileverò un bug della documentazione per aggiungerlo.
Per essere assolutamente sicuri:quote_all_identifiers
Se vuoi essere assolutamente sicuro e non preoccuparti di tutto il rumore aggiunto, puoi forzare Postgres a citare tutto identificatori con il parametro di configurazione quote_all_identifiers
. Il manuale:
Ciò include l'output di quote_ident()
e format()
. Io non fallo, temendo tutto il rumore aggiunto.
Puoi impostare il parametro localmente con SET LOCAL
nella stessa transazione. Come:
BEGIN;
SET LOCAL quote_all_identifiers = true;
SELECT ...
END;
Più veloce
Detto questo, userei format()
e concat()
e scegli come target la tabella del catalogo pg_attribute
invece:più pulito, più semplice, più veloce. Ma non portabile su altri RDBMS:
SELECT format('SELECT %s FROM %s;'
, string_agg(CASE WHEN atttypid = ANY ('{text, bpchar, varchar}'::regtype[])
THEN concat('left(', col, ', 65535) AS ', col)
ELSE col END, ', ')
, attrelid)
FROM (
SELECT attrelid::regclass, atttypid, quote_ident(attname) AS col
FROM pg_catalog.pg_attribute
WHERE attrelid = 'public."MyTableName"'::regclass -- provide once, optionally schema-qualified
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum
) sub
GROUP BY attrelid;
Produce:
SELECT id, left(first, 65535) AS first FROM "MyTableName";
db<>violino qui
In particolare, ...
- ... devi fornire il nome della tabella solo una volta, facoltativamente qualificato per lo schema.
- ... se la tabella non esiste, la query fallisce immediatamente con un utile messaggio di errore.
- ... il nome della tabella di output è qualificato dallo schema e tra virgolette se necessario.
- ... questo copre anche
character(N)
(nome internobpchar
).
Ulteriori letture:
- Come verificare se esiste una tabella in un determinato schema
- Troncamento della visualizzazione per impostazione predefinita nelle istruzioni select di postgres psql
- PostgreSQL forza maiuscolo per tutti i dati
- Verifica se sono presenti stringhe vuote nelle colonne di tipo carattere