J'ai importé le fichier Postgres SQL sur mon serveur à l'aide de Tableflus (client SQL), mais après que j'insère une nouvelle ligne, j'ai eu une erreur comme ceci:
sqlstate [23505]: Violation unique: 7 Erreur: La valeur clé en double enfreint la contrainte unique \ "users_pkey \" Détail: Touche (ID) = (1) existe déjà p> blockQuote>
Je sais que cela causé par la valeur de séquence est 0 et doit être mis à jour par code ci-dessous: p>
xxx pré> mais il faut tellement de temps si je dois écrire à toutes les séquences de table (peut-être des centaines de séquences) une à une. Alors comment mettre à jour toutes les séquences à la fois? P> p>
3 Réponses :
Vous ne pouvez pas mettre à jour toute la séquence ensemble, chaque séquence peut contenir différentes valeurs relatives à chaque tableau. Vous devez prendre la valeur max de chaque table et la mettre à jour.
SELECT setval(_sequence_name_, max(id)) FROM _table_name_;
En supposant que toutes les séquences utilisées appartiennent aux colonnes respectives, par ex. À travers un La première partie sélectionne toutes les séquences appartenant à une colonne. La deuxième partie utilise ensuite Vous voudrez peut-être exécuter cela sans le Serial code> ou
Identity code>, vous pouvez l'utiliser pour réinitialiser toutes les séquences (possédées) de la base de données actuelle.
Query_to_xml () code> pour obtenir la valeur max de la colonne associée à cette séquence. Et le choix final s'applique ensuite à la valeur maximale à chaque séquence à l'aide de
setval () code>. p>
setval () code> appel d'abord pour voir si tout est comme si vous en avez besoin. P> P>
J'ai testé sur ma base de données originale, vue fonctionnée, c'est une liste de spectacle de ma valeur de séquence et de la nouvelle valeur, mais j'ai essayé sur le serveur que j'ai importé, il affiche 0 rangées, pourquoi ??
Je pense que c'est causé par pg_get_serial_sessence n'est pas défini après l'importation dans le nouveau serveur, je exécute SELECT * de (Sélectionnez Table_Schema, Nom de table, Column_Name, PG_GET_Serial_Suence (Format (% I.% I ', Table_Schema, Nom de table), Noms de colonne) Comme Col_Sréence de l'information_schema.columns où table_schema non in ('pg_catalog', 'informations_schema')) t Où col_schequence n'est pas null code> renvoyer zéro dans nouveau serveur, mais il est renvoyé avec des données dans le serveur d'origine
pg_get_serial_Suence code> est une fonction intégrée qu'il ne peut pas "non défini". Si cette requête ne renvoie rien, vous avez perdu la propriété entre la colonne et la séquence pour une raison quelconque pendant votre "importation".
Je vois , je suis toujours en cours de contournement à l'aide de la requête colonne_default ilike 'nextval (%' code>, je veux modifier votre
col_sreence code> de pg_get_serial_fuence fonction à colonne_default. Pouvez-vous maintenant extraire
col_sessence code> à partir de colonne_default avec la valeur est "NextVal ('users_id_seq' :: regclass)". Donc, j'ai besoin d'obtenir
users_id_seq code> à partir de
NextVal ('users_id_seq' :: regclass) code>
Vous devriez plutôt corriger votre exportation / importation puis pirater avec la valeur par défaut. Si vous avez vraiment besoin de cela, veuillez poser une nouvelle question.
J'ai fait exporté / importation à l'aide de mon client SQL (Tableflus), alors je pense que rien n'est faux, mais ça va, merci. Votre réponse est utile. Je vais essayer d'abord pour vous défier, si je suis bloqué, je vais créer une nouvelle question.
Je dirais qu'il y a est b> Quelque chose ne va pas là-bas, apparemment TablePlus ne génère pas le nécessaire appartenant à code> pour les séquences. Utilisez
pg_dump code> et comparez la sortie
comme @a_horse_with_no_name La réponse ne fonctionne pas dans mon cas (peut-être que quelque chose ne va pas avec le fichier SQL), j'ai modifié la requête comme ci-dessous qui fonctionne dans mon cas.
with sequences as ( select * from ( select table_schema, table_name, column_name, replace(replace(replace(column_default, '::regclass)', ''), '''', ''), 'nextval(', 'public.') as col_sequence from information_schema.columns where table_schema not in ('pg_catalog', 'information_schema') and column_default ILIKE 'nextval(%' ) t where col_sequence is not null ), maxvals as ( select table_schema, table_name, column_name, col_sequence, (xpath('/row/max/text()', query_to_xml(format('select max(%I) from %I.%I', column_name, table_schema, table_name), true, true, '')) )[1]::text::bigint as max_val from sequences ) select table_schema, table_name, column_name, col_sequence, coalesce(max_val, 0) as max_val, setval(col_sequence, coalesce(max_val, 1)) --<< this will change the sequence from maxvals;
Si vous devez utiliser le colonne_default code> au lieu de
pg_get_serial_sessence () code> Ceci signifie que vos colonnes ne sont ni définies comme
série code> ni comme
identité code>. Je vous recommande vivement de rechercher pourquoi ce n'est pas le cas, car vous devriez vraiment utiliser cela.