J'ai essayé d'utiliser le code de Vérifiez si la séquence existe dans Postgres (plpgsql) .
Pour créer une séquence si elle n'existe pas. L'exécution de ce code deux fois provoque une exception:
séquence ... existe déjà.
Comment créer une séquence uniquement si elle n'existe pas?
Si la séquence n'existe pas, aucun message ne doit être écrit et aucune erreur ne doit se produire, je ne peux donc pas utiliser la procédure stockée dans l'autre réponse à cette question car elle écrit un message dans le fichier journal à chaque fois si la séquence existe.
do $$
begin
SET search_path = '';
IF not EXISTS (SELECT * FROM pg_class
WHERE relkind = 'S'
AND oid::regclass::text = 'firma1.' || quote_ident('myseq'))
THEN
SET search_path = firma1,public;
create sequence myseq;
END IF;
SET search_path = firma1,public;
end$$;
select nextval('myseq')::int as nr;
IF NOT EXISTS
a été ajouté à CREATE SEQUENCE
dans Postgres 9.5. Voilà la solution simple maintenant:
CREATE SEQUENCE IF NOT EXISTS myschema.myseq;
Mais considérez quand même les détails de la réponse obsolète ...
Et vous connaissez les colonnes serial
, non?
Le nom d'une séquence est en conflit avec des noms d'objets de plusieurs types, pas seulement des séquences. Le manuel:
Le nom de séquence doit être distinct du nom de toute autre séquence , table, index, vue ou table étrangère dans le même schéma.
Accentuation mienne.
Vous avez donc trois cas:
Vous devez spécifier ce que vous voulez faire dans l'un ou l'autre de ces cas. L'instruction DO
pourrait ressembler à ceci:
DO
$do$
DECLARE
_kind "char";
BEGIN
SELECT relkind
FROM pg_class
WHERE oid = 'myschema.myseq'::regclass -- sequence name, optionally schema-qualified
INTO _kind;
IF NOT FOUND THEN -- name is free
CREATE SEQUENCE myschema.myseq;
ELSIF _kind = 'S' THEN -- sequence exists
-- do nothing?
ELSE -- object name exists for different kind
-- do something!
END IF;
END
$do$;
Types d'objets (relkind
) dans pg_class
selon le manuel :
r = table ordinaire
i = index
S = séquence
v = voir
m = vue matérialisée
c = type composite
t = table TOAST
f = table étrangère
En relation:
J'ai emprunté une voie différente: il suffit de prendre l'exception:
DO
$$
BEGIN
CREATE SEQUENCE myseq;
EXCEPTION WHEN duplicate_table THEN
-- do nothing, it's already there
END
$$ LANGUAGE plpgsql;
Un avantage agréable à cela est que vous n'avez pas à vous soucier de votre schéma actuel.
Si vous n'avez pas besoin de conserver la séquence potentiellement existante, vous pouvez simplement la supprimer, puis la recréer:
DROP SEQUENCE IF EXISTS id_seq;
CREATE SEQUENCE id_seq;
Postgres n'a pas CREATE SEQUENCE IF NOT EXISTS
et si la table a une valeur par défaut en utilisant la séquence si vous déposez simplement la séquence, vous pourriez obtenir une erreur:
ERREUR: impossible de supprimer la séquence (nom_séquence) car d'autres objets en dépendent État SQL: 2BP01
Pour moi, celui-ci peut aider:
ALTER TABLE <tablename> ALTER COLUMN id DROP DEFAULT;
DROP SEQUENCE IF EXISTS <sequence_name>;
CREATE sequence <sequence_name>;
J'ai une fonction pour nettoyer toutes les tables de mon application de base de données à tout moment. Il est construit dynamiquement, mais l'essentiel est qu'il supprime toutes les données de chaque table et réinitialise la séquence. Voici le code pour réinitialiser la séquence de l'une des tables:
perform relname from pg_statio_all_sequences where relname = 'privileges_id_seq';
if found then
select setval ('privileges_id_seq',1, false) into i_result;
end if;
J'espère que cela t'aides,
Loek
J'utilise postgres 8.4, je vois que vous utilisez 9.2. Pourrait faire une différence où les informations sont stockées.
Les informations sur les séquences peuvent être récupérées à partir de information_schema.sequences
( référence )
Essayez quelque chose comme ça (non testé):
...
IF not EXISTS (SELECT * FROM information_schema.sequences
WHERE sequence_schema = 'firma1' AND sequence_name = 'myseq') THEN
...