web-dev-qa-db-ja.com

存在する場合のみ列の名前を変更する

PostgreSQLでは許可されていません

ALTER TABLE t RENAME COLUMN IF EXISTS c1 TO c2

...またはそのようなもの。ただし、DB構造を変更するスクリプトを記述して、すでに実行されているかどうかを最初に確認することなく再実行できると、非常に便利です。

これを正確に行うためにPostgreSQL関数をどのように記述しますか?

11
NessBird

こんにちはこの解決策を試してください。

DO $$
BEGIN
  IF EXISTS(SELECT *
    FROM information_schema.columns
    WHERE table_name='your_table' and column_name='your_column')
  THEN
      ALTER TABLE "public"."your_table" RENAME COLUMN "your_column" TO "your_new_column";
  END IF;
END $$;
4
Nikunj Satasiya

2つの関数を持ち、一方がもう一方を呼び出す方が良い:

CREATE OR REPLACE FUNCTION column_exists(ptable TEXT, pcolumn TEXT)
  RETURNS BOOLEAN AS $BODY$
DECLARE result bool;
BEGIN
    -- Does the requested column exist?
    SELECT COUNT(*) INTO result
    FROM information_schema.columns
    WHERE
      table_name = ptable and
      column_name = pcolumn;
    RETURN result;
END$BODY$
  LANGUAGE plpgsql VOLATILE;

CREATE OR REPLACE FUNCTION rename_column_if_exists(ptable TEXT, pcolumn TEXT, new_name TEXT)
  RETURNS VOID AS $BODY$
BEGIN
    -- Rename the column if it exists.
    IF column_exists(ptable, pcolumn) THEN
        EXECUTE FORMAT('ALTER TABLE %I RENAME COLUMN %I TO %I;',
            ptable, pcolumn, new_name);
    END IF;
END$BODY$
  LANGUAGE plpgsql VOLATILE;
2
NessBird

@NessBird 2関数のアプローチは適切ですが、Column_Exists関数は、selectが存在するように減らすことができ、カウントを回避し、plpgsql関数の代わりにSQL関数として使用できます。

create or replace function 
column_exists(ptable text, pcolumn text, pschema text default 'public')
  returns boolean 
  language sql stable strict  
as $body$
    -- does the requested table.column exist in schema?
    select exists 
         ( select null 
             from information_schema.columns 
             where table_name=ptable 
               and column_name=pcolumn 
               and table_schema=pschema
         ); 
$body$;

同じテーブル名を持つ複数のスキーマを処理するために、schemaパラメーターを追加しました。 rename_column_if_existsは、スキーマが追加される可能性がある場合を除いて、変更されません。

1
Belayer