PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

quote_ident() nie dodaje najpierw cudzysłowów do nazwy kolumny

Nie pomijaj AS słowo kluczowe dla aliasów kolumn

Nie dokładnie. Wysadza się, ponieważ pominąłeś słowo kluczowe AS gdzie nie powinno być pominięte.

To działa:

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;

Produkuje:

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

Co z kolei działa zgodnie z oczekiwaniami.

podręcznik "Pomijania JAKO słowo kluczowe” :

Można pominąć słowo kluczowe AS dla aliasów tabel, ale nie dla aliasów kolumn.

first nie jest słowem zarezerwowanym w Postgresie. (Kiedyś był „zarezerwowany” w starożytnym standardzie SQL-92, ale już nie w standardowym SQL.) Jest „niezarezerwowany” * być precyzyjnym. Podręcznik :

Pomijanie AS sprawia, że ​​jest to właśnie taki kontekst.

quote_ident() działa niezawodnie. Podręcznik:

format() ze specyfikatorem %I robi to samo.

Zarezerwowane słowa nie są wymieniane, ale są cytowane prawidłowo. Mówiąc dokładniej:wszystkie słowa kluczowe oznaczone jako „zarezerwowane” lub „(nie może być funkcją ani typem)” w kolumnie „PostgreSQL” Słowa kluczowe SQL stół .

Zgłoszę błąd w dokumentacji, aby to dodać.

Aby mieć absolutną pewność:quote_all_identifiers

Jeśli chcesz mieć absolutną pewność i nie przeszkadza ci cały dodatkowy hałas, możesz zmusić Postgresa do cytowania wszystkich identyfikatory z parametrem konfiguracyjnym quote_all_identifiers . Podręcznik:

Obejmuje to dane wyjściowe z quote_ident() i format() . nie zrób to, bojąc się wszystkich dodatkowych hałasów.

Możesz ustawić parametr lokalnie za pomocą SET LOCAL w tej samej transakcji. Na przykład:

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

Szybciej

To powiedziawszy, użyłbym format() i concat() i wybierz tabelę katalogu pg_attribute zamiast tego:czyściej, prościej, szybciej. Ale nie można go przenieść do innych 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;

Produkuje:

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

db<>fiddle tutaj

W szczególności ...

  • ... wystarczy podać nazwę tabeli tylko raz, opcjonalnie kwalifikowana według schematu.
  • ... jeśli tabela nie istnieje, zapytanie natychmiast kończy się niepowodzeniem i wyświetla pomocny komunikat o błędzie.
  • ... nazwa tabeli wyjściowej jest kwalifikowana tylko zgodnie ze schematem i w razie potrzeby w cudzysłowie.
  • ... obejmuje to również character(N) (nazwa wewnętrzna bpchar ).

Dalsza lektura:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy mogę "ponownie skompilować" funkcje zwracające tabelę po tym, jak ta tabela zostanie zmieniona podczas migracji bazy danych?

  2. pg_restore nie może wykonać zapytania:BŁĄD:nieprawidłowa nazwa lokalizacji:en_US.UTF-8

  3. Dlaczego w PostgreSQL typu enum array dozwolone są wartości null?

  4. Rails 3, Heroku:Taps Server Error:PGError:ERROR:nieprawidłowa sekwencja bajtów do kodowania UTF8:0xba

  5. Podobne ciągi UTF-8 dla pola autouzupełniania