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?
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.