Не пропускайте AS
ключова дума за псевдоними на колони
Не точно. Издухва се, защото сте пропуснали ключовата дума AS
където не трябва да се пропуска.
Това работи:
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;
Произвежда:
SELECT id, left(first, 65535) AS first from "public"."MyTableName";
Което на свой ред работи според очакванията.
ръководството за "Пропускане на AS ключова дума“ :
Добре е да пропуснете ключовата дума AS
за псевдоними на таблици, но не и за псевдоними на колони.
first
не е запазена дума
в Postgres. (Беше „запазен“ в древния SQL стандарт SQL-92, но вече не и в стандартния SQL.) Той е „незапазен“ * за да бъдем точни. Ръководството
:
Пропуска се AS
го прави точно такъв контекст.
quote_ident()
работи надеждно. Ръководството:
format()
със спецификатора %I
прави същото.
Запазените думи не се споменават, но се цитират правилно. За да бъдем точни:всички ключови думи, отбелязани с "резервирани" или "(не може да бъде функция или тип)" в колоната „PostgreSQL“ на SQL ключови думи таблица .
Ще подам документация за грешка, за да добавя това.
За да сте абсолютно сигурни:quote_all_identifiers
Ако искате да сте абсолютно сигурни и нямате нищо против целия добавен шум, можете да принудите Postgres да цитира всички идентификатори с конфигурационния параметър quote_all_identifiers
. Ръководството:
Това включва изход от quote_ident()
и format()
. Бихнебих направете това, страхувайки се от добавения шум.
Можете да зададете параметъра локално с SET LOCAL
в същата сделка. Като:
BEGIN;
SET LOCAL quote_all_identifiers = true;
SELECT ...
END;
По-бързо
Въпреки това бих използвал format()
и concat()
и се насочете към каталожната таблица pg_attribute
вместо това:по-чисто, по-лесно, по-бързо. Но не е преносим към други 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;
Произвежда:
SELECT id, left(first, 65535) AS first FROM "MyTableName";
db<>fiddle тук
По-специално, ...
- ... трябва да предоставите името на таблицата само веднъж, по избор квалифицирано като схема.
- ... ако таблицата не съществува, заявката се проваля веднага с полезно съобщение за грешка.
- ... името на изходната таблица е само квалифицирано като схема и в двойни кавички, където е необходимо.
- ... това също обхваща
character(N)
(вътрешно имеbpchar
).
Допълнителна информация:
- Как да проверя дали таблица съществува в дадена схема
- Съкращаване на дисплея по подразбиране в оператори за избор на postgres psql
- PostgreSQL принуждава главни букви за всички данни
- Проверете дали има празни низове в колони от тип символ