web-dev-qa-db-fra.com

Renommer la colonne uniquement s'il existe

PostgreSQL ne permet pas

ALTER TABLE t RENAME COLUMN IF EXISTS c1 TO c2

... ou quelque chose comme ça. Cependant, il est très pratique de pouvoir écrire des scripts qui modifient la structure de la base de données qui peuvent être exécutés à nouveau sans vérifier d'abord si elle a déjà été exécutée.

Comment écrire une fonction PostgreSQL pour faire exactement cela?

11
NessBird

HI Essayez cette solution.

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

Mieux vaut avoir deux fonctions, l'une appelant l'autre:

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

L'approche de la fonction @NessBird 2 est bonne mais la fonction Column_Exists peut être réduite à une sélection existe, en évitant de compter, et en tant que fonction SQL au lieu d'une fonction plpgsql.

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

J'ai ajouté le paramètre de schéma pour gérer plusieurs schémas avec le même nom de table. Rename_column_if_exists reste inchangé à l'exception de l'ajout possible de schéma.

1
Belayer