Pytanie PostgreSQL - wartość dynamiczna jako nazwa tabeli [duplicate]


Możliwe duplikaty:
Funkcja kwerendy dynamicznej PostgreSQL 

Chciałbym użyć zwracanego ciągu z poniższego zapytania jako nazwy tabeli dla innego zapytania.

SELECT 'backup_' || TO_CHAR(CURRENT_DATE,'yyyy-mm-dd')

jak widać zwróci ciąg znaków. Chciałbym użyć go jako danych wejściowych dla innego zapytania, np.

CREATE TABLE (SELECT 'backup_' || TO_CHAR(CURRENT_DATE,'yyyy-mm-dd')) 
AS * SELECT FROM backup

Czy można to zrobić? Jakąkolwiek wskazówkę?


15
2017-11-08 12:37


pochodzenie


Mam rozwiązanie, które nie ma zastosowania stackoverflow.com/questions/10639963/... ale interesujące dla tego problemu: SELECT "" backup_ "|| TO_CHAR (CURRENT_DATE," yyyy-mm-dd ") || '"' AS nazwa; \ gset CREATE TABLE: tname AS SELECT * FROM backup; - Roman Tkachuk


Odpowiedzi:


Będziesz musiał użyć PL / PgSQL EXECUTE komunikat, poprzez DO blok lub funkcja PL / PgSQL (CREATE OR REPLACE FUNCTION ... LANGUAGE plpgsql). Dynamiczny SQL nie jest obsługiwany w zwykłym dialekcie SQL używanym przez PostgreSQL, tylko w proceduralnym wariancie PL / PgSQL.

DO
$$
BEGIN
EXECUTE format('CREATE TABLE %I AS SELECT * FROM backup', 'backup_' || to_char(CURRENT_DATE,'yyyy-mm-dd'));
END;
$$ LANGUAGE plpgsql;

The format(...) funkcjonować„s %I i %L specyfikatory formatów odpowiednio wpisują właściwy identyfikator i literalne cytowanie.

W przypadku literałów polecam używanie EXECUTE ... USING zamiast format(...) z %L, ale w przypadku identyfikatorów takich jak tabela / kolumna określa format %I wzór jest ładną zwięzłą alternatywą dla gadatliwego quote_ident połączenia.


32
2017-11-08 13:33



Czy nazwa będzie automatycznie cytowana, jeśli zawiera znaki specjalne? Nie jestem tak naprawdę użytkownikiem PostgreSQL, ale wydaje się wątpliwe, czy prosta funkcja FORMAT () byłaby na tyle sprytna, aby to zrobić. - Andriy M
@AndriyM The %I interpolacja zastępcza w format() funkcja jest specyficzna dla identyfikatorów postgres i bezpiecznie zacytuje dostarczoną wartość. - dbenhur
@dbenhur: Oh, dobrze, dzięki. Dobre rozwiązanie, Craig! (widocznie :) - Andriy M