web-dev-qa-db-ja.com

PostgreSQLでタイプregclassのテーブルのスキーマ名を取得する方法は?

列_col_name_がテーブル__tbl_に存在するかどうかをテストする関数を記述する際に、regclassパラメータとして関数に渡されるテーブルのスキーマ名を抽出します(セキュリティのため??).

_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;
_

したがって、テーブル名が_'staging.my_table'::regclass_の場合、架空の関数_get_schema_からstagingを取得します。

この関数をsplit_part(_tbl::text, '.', 1)などで実装できますか?

さらに、テーブル名__tbl_がテキストに変換されたときに、常にスキーマ名を持つことが保証されますか?(つまり、_public._)などを省略しないでください

regclassタイプについてはあまり詳しくありません。私は検索しましたが、スキーマ名を抽出する方法を見つけることができませんでした。ホイールを再発明する前に、最初に質問したいと思いました。

4
tinlyx

この機能を実装することはできますか? split_part(_tbl::text, '.', 1)

それが安全かどうかはわかりません。代わりに、私は使用します、

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;

それは動作することが保証されています。

col_nameがテーブル_tblに存在するかどうかをテストする関数を記述する際に、regclassパラメータとして関数に渡されるテーブルのスキーマ名を抽出したいと思います(セキュリティのため?? )。

だからあなたは次のようなことをすることができます、

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;

更新

内部にテーブル名とスキーマ名を持つ完全修飾識別子がある場合、 parse_ident を使用して安全に解析できます。

6
Evan Carroll

さらに簡単にするために、Postgres 9.5で導入された regnamespace-別のオブジェクト識別子タイプ へのキャストを使用できます。

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

オブジェクト識別子タイプをtextにキャストすると、完全修飾(現在のsearch_pathで必要な場合のみ)および二重引用符で囲まれた(必要な場合のみ)文字列が生成されます。

ただし、 pg_attribute を直接操作する場合は、これは必要ありません。

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;

よりシンプル、より短く、より速く。

3