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

Funkcja zwracająca dynamiczny zestaw kolumn dla danej tabeli

Rozwiązanie dla prostego przypadku

Jak wyjaśniono w przywołanych odpowiedziach poniżej, możesz użyć zarejestrowanych typów (wierszów), a tym samym niejawnie zadeklarować typ zwracany funkcji polimorficznej:

CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;

Zadzwoń:

SELECT * FROM public.get_table(NULL::public.users);  -- note the syntax!

Zwraca pełną tabelę (ze wszystkimi kolumnami użytkownika).

Czekaj! Jak?

Szczegółowe wyjaśnienie w tej powiązanej odpowiedzi, rozdział„Różne kompletne typy tabel” :

  • Refaktoryzuj funkcję PL/pgSQL, aby zwrócić dane wyjściowe różnych zapytań SELECT

TABLE foo to po prostu skrót od SELECT * FROM foo :

  • Czy istnieje skrót do SELECT * FROM?

2 kroki dla całkowicie dynamicznego typu zwrotu

Ale to, co próbujesz zrobić, jest całkowicie niemożliwe w single polecenie SQL.

Chcę przekazać schema_name i table_name jako parametry do działania i uzyskania listy rekordów, zgodnie z column_visible pole w public.fields tabeli.

Nie ma bezpośredniego sposobu na zwrócenie arbitralnie wybranych kolumn (typ zwracania nieznany w czasie wywołania) z funkcji — lub dowolnego Polecenie SQL. SQL wymaga znajomości liczby, nazw i typów wynikowych kolumn w czasie połączenia. Więcej w drugim rozdziale tej powiązanej odpowiedzi:

  • Jak wygenerować przestawne CROSS JOIN, gdy wynikowa definicja tabeli jest nieznana?

Istnieją różne obejścia . Możesz zawinąć wynik w jeden ze standardowych typów dokumentów (json , jsonb , hstore , xml ).

Lub generujesz zapytanie jednym wywołaniem funkcji i wykonujesz wynik następnym:

CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
  RETURNS text AS
$func$
   SELECT format('SELECT %s FROM %I.%I'
               , string_agg(quote_ident(column_name), ', ')
               , schema_name
               , table_name)
   FROM   fields
   WHERE  column_visible
   AND    schema_name = _schema_name 
   AND    table_name  = _table_name
   GROUP  BY schema_name, table_name
   ORDER  BY schema_name, table_name;
$func$  LANGUAGE sql;

Zadzwoń:

SELECT public.generate_get_table('public', 'users');

Spowoduje to utworzenie zapytania w postaci:

SELECT usr_id, usr FROM public.users;

Wykonaj go w drugim kroku. (Możesz dodać numery kolumn i kolejność kolumn.)
Lub dołącz \gexec w psql, aby natychmiast wykonać zwracaną wartość. Zobacz:

Jak wymusić ocenę podzapytania przed dołączeniem / zepchnięciem na obcy serwer

Zabezpiecz się przed wstrzyknięciem SQL:

  • WSTAW z dynamiczną nazwą tabeli w funkcji wyzwalacza
  • Zdefiniować nazwy tabel i kolumn jako argumenty w funkcji plpgsql?
na bok

varchar(100) nie ma większego sensu w przypadku identyfikatorów, które są ograniczone do 63 znaków w standardowym Postgresie:

  • Maksymalna liczba znaków w etykietach (nazwy tabel, kolumny itp.)

Jeśli rozumiesz, w jaki sposób identyfikator obiektu wpisz regclass działa, możesz zastąpić nazwę schematu i tabeli pojedynczą regclass kolumna.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Łączenie się z bazą danych PostgreSQL przez tunelowanie SSH w Pythonie

  2. Porównanie typów kolumn baz danych w MySQL, PostgreSQL i SQLite? (Mapowanie krzyżowe)

  3. Wielokrotne wywołanie funkcji zwracającej zestaw z argumentem tablicowym

  4. jak poprzedzić ciąg przed sekwencją wygenerowaną przez postgresql?

  5. Jak posortować wynik z string_agg()