sql >> Databáze >  >> RDS >> PostgreSQL

quote_ident() nejprve nepřidává uvozovky k názvu sloupce

Nevynechejte AS klíčové slovo pro aliasy sloupců

Nepřesně. Vybuchne, protože jste vynechali klíčové slovo AS kde by neměl být vynechán.

Funguje to:

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;

Vyrábí:

SELECT id, left(first, 65535) AS first from "public"."MyTableName";

Což zase funguje podle očekávání.

příručka o "Vynechání Klíčové slovo AS" :

Klíčové slovo AS je v pořádku vynechat pro aliasy tabulek, ale ne pro aliasy sloupců.

first není rezervované slovo v Postgresu. (Býval „rezervovaný“ ve starém SQL standardu SQL-92, ale již ne ve standardním SQL.) Je „nerezervovaný“ * být přesný. Příručka :

Vynechání AS dělá z toho přesně takový kontext.

quote_ident() funguje spolehlivě. Příručka:

format() se specifikátorem %I dělá totéž.

Vyhrazená slova nejsou uvedena, ale bez ohledu na to správně citována. Pro upřesnění:všechna klíčová slova označena "rezervováno" nebo "(nemůže být funkce nebo typ)" ve sloupci "PostgreSQL" Klíčová slova SQL tabulka .

Napíšu chybu v dokumentaci, abych to přidal.

Abyste si byli naprosto jisti:quote_all_identifiers

Pokud si chcete být naprosto jisti a nevadí vám všechen ten přidaný hluk, můžete Postgres donutit, aby citoval vše identifikátory s konfiguračním parametrem quote_all_identifiers . Příručka:

To zahrnuje výstup z quote_ident() a format() . Já bych ne udělejte to, děsíte se veškerého přidaného hluku.

Parametr můžete nastavit lokálně pomocí SET LOCAL ve stejné transakci. Jako:

BEGIN;
SET LOCAL quote_all_identifiers = true;
SELECT ...
END;

Rychlejší

To znamená, že bych použil format() a concat() a cílit na tabulku katalogu pg_attribute místo toho:čistší, jednodušší, rychlejší. Nelze však přenést na jiné 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;

Vyrábí:

SELECT id, left(first, 65535) AS first FROM "MyTableName";

db<>fiddle zde

Zejména ...

  • ... název tabulky musíte zadat pouze jednou, volitelně s kvalifikací pro schéma.
  • ... pokud tabulka neexistuje, dotaz okamžitě selže s užitečnou chybovou zprávou.
  • ... název výstupní tabulky je kvalifikován pouze podle schématu a v případě potřeby je uveden ve dvojitých uvozovkách.
  • ...toto se vztahuje také na character(N) (interní název bpchar ).

Další čtení:




  1. Mysql show vytvořit omezení?

  2. Nelze zobrazit obrázek pomocí php a mysql

  3. Co je databáze? A DBMS?

  4. Jak najít kolace databáze podporované vaší instancí SQL Server