it-swarm.com.de

Wie erhalte ich den Schemanamen einer Tabelle vom Typ regclass in PostgreSQL?

Beim Schreiben einer Funktion zum Testen, ob eine Spalte col_name in einer Tabelle _tbl vorhanden ist, möchte ich den Schemanamen der Tabelle extrahieren, der als regclass an die Funktion übergeben wird Parameter (aus Sicherheitsgründen ??).

CREATE OR REPLACE FUNCTION column_exists(_tbl regclass, col_name text)
  RETURNS bool AS
$func$
  SELECT EXISTS (
    SELECT 1 FROM information_schema.columns 
    WHERE table_schema=get_schema($1) 
      AND table_name=get_table($1) 
      AND column_name=$2
    );
$func$  LANGUAGE sql;

Wenn der Tabellenname also 'staging.my_table'::regclass ist, möchte ich staging von einer imaginären Funktion get_schema erhalten.

Kann ich diese Funktion einfach mit z. B. split_part(_tbl::text, '.', 1) implementieren?

Ist außerdem garantiert, dass der Tabellenname _tbl bei der Konvertierung in Text immer einen Schemanamen hat? (D. H. Dinge wie public. nicht auslassen

Ich bin mit dem Typ regclass nicht sehr vertraut. Ich suchte, konnte aber nicht finden, wie ich den Schemanamen extrahieren konnte, und wollte nur zuerst fragen, bevor ich die Räder neu erfand.

4
tinlyx

Kann ich diese Funktion einfach mit z. split_part(_tbl::text, '.', 1)?

Ich bin mir nicht sicher, ob das sicher wäre. Stattdessen würde ich verwenden,

SELECT nspname
FROM pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS ns
  ON c.relnamespace = ns.oid
WHERE c.oid = _tbl;

Das wird garantiert funktionieren.

Beim Schreiben einer Funktion zum Testen, ob eine Spalte col_name existiert in einer Tabelle _tbl, Ich möchte den Schemanamen der Tabelle extrahieren, der als Regclass-Parameter an die Funktion übergeben wird (aus Sicherheitsgründen ??).

Sie könnten also so etwas tun,

SELECT nspname
FROM pg_catalog.pg_attribute AS a
JOIN pg_catalog.pg_class AS c
  ON a.attrelid = c.oid
JOIN pg_catalog.pg_namespace AS ns
  ON c.relnamespace = ns.oid
WHERE c.oid = _tbl
  AND a.attname = col_name;

Aktualisieren

Wenn Sie eine vollständig qualifizierte Kennung haben, eine mit dem Tabellennamen und dem Schemanamen, können Sie parse_ident um es sicher zu analysieren.

6
Evan Carroll

Zur weiteren Vereinfachung können Sie eine Umwandlung in regnamespace - einen anderen Objektkennungstyp verwenden, die mit Postgres 9.5 eingeführt wurde

SELECT relnamespace::regnamespace::text
FROM   pg_catalog.pg_class
WHERE  oid = _tbl;

Das Umwandeln eines Objektkennungstyps in text erzeugt eine vollständig qualifizierte (nur wenn das aktuelle search_path erfordert es) und doppelte (nur bei Bedarf) Zeichenfolge.

Aber Sie brauchen nichts davon, wenn Sie mit pg_attribute direkt:

CREATE OR REPLACE FUNCTION pg_temp.column_exists(_tbl regclass, _col_name text)
   RETURNS bool AS
$func$
SELECT EXISTS (
   SELECT FROM pg_catalog.pg_attribute
   WHERE attrelid = _tbl
   AND   attname = _col_name
   );
$func$  LANGUAGE sql;

Einfacher, kürzer, schneller.

3