101 votes

Obtenir le nombre d'enregistrements affectés par INSERT ou UPDATE dans PostgreSQL

Mon pilote de base de données pour PostgreSQL 8/9 ne renvoie pas un nombre d'enregistrements affectés lors de l'exécution de INSERT ou UPDATE.

PostgreSQL offre la syntaxe non standard "RETURNING" qui semble être une bonne solution de contournement. Mais quelle pourrait être la syntaxe? L'exemple renvoie l'ID d'un enregistrement, mais j'ai besoin d'un compte.

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING did;

157voto

mercurial Points 788

Je sais que cette question est viiiieille et ma solution est sans doute trop complexe, mais c'est mon type de solution préféré !

Quoi qu'il en soit, j'ai dû faire la même chose et j'ai réussi à le faire fonctionner comme ça :

-- Obtenir le nombre d'INSERT
WITH rows AS (
    INSERT INTO distributors
        (did, dname)
    VALUES
        (DEFAULT, 'Widgets XYZ'),
        (DEFAULT, 'Widgets ABC')
    RETURNING 1
)
SELECT count(*) FROM rows;

-- Obtenir le nombre d'UPDATE
WITH rows AS (
    UPDATE distributors
    SET dname = 'Widgets JKL'
    WHERE did <= 10
    RETURNING 1
)
SELECT count(*) FROM rows;

Un de ces jours, je devrai vraiment écrire un sonnet d'amour sur la clause WITH de PostgreSQL...

40voto

Scott Bailey Points 2094

Je suis d'accord avec Milen, votre conducteur devrait le faire pour vous. Quel conducteur utilisez-vous et pour quelle langue? Mais si vous utilisez plpgsql, vous pouvez utiliser GET DIAGNOSTICS my_var = ROW_COUNT;

http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS

31voto

Igor Cova Points 619

Vous pouvez prendre ROW_COUNT après la mise à jour ou l'insertion avec ce code :

insert into distributors (did, dname) values (DEFAULT, 'XYZ Widgets');
get diagnostics v_cnt = row_count;

1voto

Chris Halcrow Points 907

Vous pourriez envelopper votre requête dans une transaction et cela devrait vous montrer le nombre avant que vous ROLLBACK ou COMMIT. Exemple :

BEGIN TRANSACTION;

INSERT .... ;

ROLLBACK TRANSACTION;

Si vous exécutez les 2 premières lignes ci-dessus, cela devrait vous donner le compte. Vous pouvez ensuite ROLLBACK (annuler) l'insertion si le nombre de lignes affectées n'est pas ce que vous attendiez. Si vous êtes satisfait que l'INSERT est correct, alors vous pouvez exécuter la même chose, mais remplacer la ligne 3 par COMMIT TRANSACTION;.

Note importante : Après avoir exécuté un BEGIN TRANSACTION; vous devez soit ROLLBACK; soit COMMIT; la transaction, sinon la transaction créera un verrou qui peut ralentir ou même paralyser tout un système, si vous travaillez dans un environnement de production.

0voto

beldaz Points 1432

Il n'est pas clair dans votre question comment vous appelez l'instruction. En supposant que vous utilisiez quelque chose comme JDBC, vous l'appelez peut-être en tant que requête plutôt qu'en tant que mise à jour. D'après executeQuery de JDBC:

Exécute l'instruction SQL donnée, qui renvoie un seul objet ResultSet.

C'est donc approprié lorsque vous exécutez une instruction qui renvoie quelques résultats de requête, tels que SELECT ou INSERT ... RETURNING. Si vous effectuez une mise à jour de la base de données puis souhaitez connaître le nombre de tuples affectés, vous devez utiliser executeUpdate qui renvoie:

soit (1) le nombre de lignes pour les instructions du langage de manipulation de données SQL (DML) soit (2) 0 pour les instructions SQL qui ne renvoient rien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X