Postgresql-Funktion zum Erstellen einer Tabelle

9

Ich möchte eine Funktion erstellen, um eine Tabelle mit einer bestimmten Struktur zu erstellen, die einen Teil des Tabellennamens als Argument verwendet, sodass der Name der Tabelle t_ lautet. Ähnlich wie dies:

CREATE OR REPLACE FUNCTION create_table_type1(t_name VARCHAR(30)) RETURNS VOID AS $$
BEGIN
    EXECUTE "CREATE TABLE IF NOT EXISTS t_"|| t_name ||"
    (
    id SERIAL,
    customerid INT,
    daterecorded DATE,
            value DOUBLE PRECISION,
    PRIMARY KEY (id)
    )"
END
$$ LANGUAGE plpgsql

Dann nenne es wie:

SELECT create_table_type1('one');

Ist es möglich?

Alan Cor
quelle

Antworten:

19

Die Antwort lautet ja . :) :)

CREATE OR REPLACE FUNCTION create_table_type1(t_name varchar(30))
  RETURNS VOID AS
$func$
BEGIN

EXECUTE format('
   CREATE TABLE IF NOT EXISTS %I (
    id serial PRIMARY KEY,
    customerid int,
    daterecorded date,
    value double precision
   )', 't_' || t_name);

END
$func$ LANGUAGE plpgsql;

Ich verwende format()mit %I, um den Tabellennamen zu bereinigen und SQL-Injection zu vermeiden. Benötigt PostgreSQL 9.1 oder höher.

Stellen Sie sicher, dass Sie für Daten einfache Anführungszeichen ( '') verwenden. Doppelte Anführungszeichen ( "") stehen für Bezeichner in SQL.

Erwin Brandstetter
quelle
Nochmals vielen Dank, es funktioniert, aber Sie haben einen kleinen Fehler. Es sollte 'TABELLE ERSTELLEN, WENN% I NICHT EXISTIERT' sein, oder?
Alan Cor
@ user1350102: Richtig, geht der Name der Tabelle nach IF NOT EXISTS . Danke, geändert.
Erwin Brandstetter
@ErwinBrandstetter, könnten wir $$ ... $$ LANGUAGE plpgsql;statt verwenden $func$ ... $func$ LANGUAGE plpgsql;? Was ist der Unterschied zwischen diesen beiden? Gibt es eine Situation, in der einer dem anderen vorzuziehen ist? Ich frage mich, weil ich das erstere benutzt habe.
Dw8547
@ dw8547: Du könntest. Keine Bedeutung. Es ist nur ein Dollar-Kurs. Siehe: stackoverflow.com/questions/12144284/… . Ich benutze $func$statt nur $$zur Klarheit und um Probleme mit verschachtelten Dollar- Notierungen zu vermeiden.
Erwin Brandstetter
2

ja das ist möglich Sie müssen jedoch ein wenig vorsichtig sein. DDLs in einer gespeicherten Prozedur funktionieren normalerweise. In einigen bösen Eckfällen kann es zu "Cache-Lookup" -Fehlern kommen. Der Grund dafür ist, dass eine Prozedur im Grunde genommen Teil einer Anweisung ist und das Ändern dieser Systemobjekte im laufenden Betrieb in seltenen Fällen zu Fehlern führen kann (muss). Dies kann jedoch mit CREATE TABLE nicht passieren. Sie sollten also in Sicherheit sein.

Hans-Jürgen Schönig
quelle