Uteslut inte AS
nyckelord för kolumnalias
Inte exakt. Det exploderar eftersom du har utelämnat sökordet AS
där den inte bör utelämnas.
Detta fungerar:
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;
Producerar:
SELECT id, left(first, 65535) AS first from "public"."MyTableName";
Vilket fungerar som förväntat i sin tur.
manualen om "Utelämna AS nyckelord" :
Det är OK att utelämna nyckelordet AS
för tabellalias, men inte för kolumnalias.
first
är inte ett reserverat ord
i Postgres. (Det brukade vara "reserverat" i den gamla SQL-standarden SQL-92, men inte längre i standard SQL heller.) Det är "icke-reserverat" * att vara precis. Handboken
:
Utelämnar AS
gör det till ett sådant sammanhang.
quote_ident()
fungerar tillförlitligt. Handboken:
format()
med specifikationen %I
gör detsamma.
Reserverade ord nämns inte, men citeras korrekt oavsett. För att vara exakt:alla nyckelord märkta med "reserverad" eller "(kan inte vara funktion eller typ)" i kolumnen "PostgreSQL" i SQL-nyckelord bord .
Jag skickar en dokumentationsbugg för att lägga till det.
För att vara helt säker:quote_all_identifiers
Om du vill vara helt säker och inte har något emot allt extra brus, kan du tvinga Postgres att citera alla identifierare med konfigurationsparametern quote_all_identifiers
. Handboken:
Det inkluderar utdata från quote_ident()
och format()
. Jag skulle inte gör det, fruktar allt extra brus.
Du kan ställa in parametern lokalt med SET LOCAL
i samma transaktion. Gilla:
BEGIN;
SET LOCAL quote_all_identifiers = true;
SELECT ...
END;
Snabbare
Som sagt, jag skulle använda format()
och concat()
och rikta in sig på katalogtabellen pg_attribute
istället:renare, enklare, snabbare. Men inte portabel till andra 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;
Producerar:
SELECT id, left(first, 65535) AS first FROM "MyTableName";
db<>fiol här
Särskilt ...
- ... du behöver bara ange tabellnamnet en gång, eventuellt schemakvalificerat.
- ... om tabellen inte finns, misslyckas frågan omedelbart med ett användbart felmeddelande.
- ... namnet på utdatatabellen är endast schemakvalificerat och citeras vid behov.
- ... detta omfattar även
character(N)
(internt namnbpchar
).
Mer läsning:
- Hur man kontrollerar om en tabell finns i ett givet schema
- Trunkering visas som standard i postgres psql select-satser
- PostgreSQL forcerar versaler för all data
- Kontrollera om tomma strängar finns i teckentypskolumner