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

Zdefiniować nazwy tabel i kolumn jako argumenty w funkcji plpgsql?

Musisz bronić się przed wstrzyknięciem SQL za każdym razem, gdy zamieniasz dane wprowadzone przez użytkownika w kod. Obejmuje to nazwy tabel i kolumn pochodzące z katalogów systemowych lub z bezpośrednich danych wejściowych użytkownika. W ten sposób zapobiegasz również trywialnym wyjątkom z niestandardowymi identyfikatorami. Zasadniczo są trzy wbudowane metody:

1. format()

Pierwsze zapytanie, oczyszczone:

CREATE OR REPLACE FUNCTION foo(_t text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format('
   ALTER TABLE %I ADD COLUMN c1 varchar(20)
                , ADD COLUMN c2 varchar(20)', _t);
END
$func$;

format() wymaga Postgresa 9.1 lub nowszego. Użyj go z %I specyfikator formatu.

Sama nazwa tabeli może być niejednoznaczna. Być może będziesz musiał podać nazwę schematu, aby uniknąć przypadkowej zmiany niewłaściwej tabeli. Powiązane:

  • WSTAW z dynamiczną nazwą tabeli w funkcji wyzwalacza
  • W jaki sposób search_path wpływa na rozpoznawanie identyfikatora i „bieżący schemat”

Na bok:dodawanie wielu kolumn z jedną ALTER TABLE polecenie jest tańsze.

2. regclass

Możesz także użyć rzutowania na zarejestrowaną klasę (regclass ) dla szczególnego przypadku istniejącego nazwy tabel. Opcjonalnie kwalifikowana schematem. To kończy się niepowodzeniem natychmiast i wdzięcznie w przypadku nazw tabel, które nie są prawidłowe i widoczne dla użytkownika wywołującego. Pierwsze zapytanie oczyszczone za pomocą rzutowania do regclass :

CREATE OR REPLACE FUNCTION foo(_t regclass)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE 'ALTER TABLE ' || _t || ' ADD COLUMN c1 varchar(20)
                                   , ADD COLUMN c2 varchar(20)';
END
$func$;

Zadzwoń:

SELECT foo('table_name');

Lub:

SELECT foo('my_schema.table_name'::regclass);

Na bok:rozważ użycie tylko text zamiast varchar(20) .

3. quote_ident()

Oczyszczone drugie zapytanie:

CREATE OR REPLACE FUNCTION foo(_t regclass, _c text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE 'UPDATE ' || _t    -- sanitized with regclass
        || ' SET ' || quote_ident(_c) || ' = ''This is a test''';
END
$func$;

Dla wielu konkatenacji / interpolacji, format() jest czystszy ...

Powiązane odpowiedzi:

  • Nazwa tabeli jako parametr funkcji PostgreSQL
  • Funkcje Postgres a przygotowane zapytania

Rozróżniana wielkość liter!

Pamiętaj, że niecytowane identyfikatory nie oddaj tutaj małe litery. W przypadku użycia jako identyfikator w SQL [Postgres automatycznie odwzorowuje małe litery][7]. Ale tutaj przekazujemy stringi dla dynamicznego SQL. Po opuszczeniu, jak pokazano, identyfikatory CaMel-case (takie jak UserS ) zostanie zachowany przez podwójne cudzysłowy ("UserS" ), podobnie jak inne niestandardowe nazwy, takie jak "name with space" "SELECT" itp. W związku z tym w nazwach rozróżniana jest wielkość liter.

Moją stałą radą jest używanie wyłącznie prawnych identyfikatorów małymi literami i nie martw się o to.

Poza tym:pojedyncze cudzysłowy dotyczą wartości, podwójne cudzysłowy dotyczą identyfikatorów. Zobacz:

  • https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak połączyć Postgres z serwerem localhost za pomocą pgAdmin na Ubuntu?

  2. Jak działają widoki bariery bezpieczeństwa PostgreSQL?

  3. Jak wdrożyć PostgreSQL w kontenerze Docker za pomocą ClusterControl

  4. Najlepsze materiały szkoleniowe i szkoleniowe dotyczące PostgreSQL

  5. hasMany wywołało coś, co nie jest instancją Sequelize.Model