Insertion de données dans une table SQL avec clé primaire. Pour les dupes - autorisez l'erreur d'insertion ou sélectionnez d'abord?

StackOverflow https://stackoverflow.com/questions/411575

  •  03-07-2019
  •  | 
  •  

Question

Étant donné un tableau tel que:

CREATE TABLE dbo.MyTestData (testdata varchar(50) NOT NULL) 

ALTER TABLE dbo.MyTestData WITH NOCHECK ADD CONSTRAINT [PK_MyTestData] PRIMARY KEY  CLUSTERED (testdata) 

Et étant donné que nous voulons une liste unique de 'données de test' lorsque nous avons terminé de rassembler les éléments à ajouter à partir d'une liste de données externes avec des doublons connus ... Lors de l'exécution d'une procédure d'insertion stockée, cette procédure doit-elle être écrite pour le test existence ou devrait-il simplement permettre l'erreur? Quelle est la pratique la plus courante? J'ai toujours effectué le test d'existence, mais je débattais de cela hier soir ...

CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
  SET NOCOUNT ON

  IF NOT EXISTS(SELECT testdata FROM dbo.MyTestData WHERE testdata=@ptestdata)
  BEGIN
    INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
  END

RETURN 0

ou simplement capturer / ignorer les erreurs de violation de clé lors de l’exécution de celle-ci?

CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
  SET NOCOUNT ON
  INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
RETURN 0
Était-ce utile?

La solution

Je le fais toujours dans une déclaration:

INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
WHERE NOT EXISTS(SELECT 1 FROM dbo.MyTestData WHERE testdata=@ptestdata)

Autres conseils

Votre recherche d'erreurs (par exemple, "SI NON EXISTE ...") peut ou peut ne pas fonctionner car il existe une condition de concurrence éventuelle (si une autre transaction insère l'enregistrement après votre instruction IF NOT EXISTS mais avant votre instruction INSERT. ).

Par conséquent, que vous vérifiiez ou non auparavant, vous devez coder votre instruction INSERT comme si elle risquait d’échouer.

Indiquez si vous souhaitez également vérifier (pas à votre place) et votre interface utilisateur.

Je pense que la plupart des programmeurs suggéreraient d'éviter l'exception. Je ne suis pas sûr du point de vue des performances dans T-SQL, mais dans .NET par exemple, je pense qu'une exception levée est plus coûteuse qu'une déclaration if / else supplémentaire.

Le premier exemple que vous avez donné me préoccupe: il ne renvoie pas d'erreur à l'utilisateur. Cela peut être corrigé, mais je ne l’utiliserais pas à moins qu’il ne renvoie une erreur.

Si votre préoccupation entre les deux possibilités est la performance sur de grandes tables, je vous suggère de tester les deux et de voir si l’une est nettement plus rapide que l’autre. Si la sélection if est particulièrement compliquée et que l'insertion doit se produire la plupart du temps, il est possible que le laisser échouer soit plus rapide la plupart du temps. Si, en revanche, la possibilité d’une mauvaise entrée est élevée et si le processus if est relativement simple, comme indiqué ci-dessous, l’autre processus pourrait être meilleur. Mais seuls des tests réels sur votre structure de données et vos données réelles et sur vos requêtes réelles peuvent vous indiquer quel est le meilleur en termes de performances, car il peut être différent selon les situations.

Je pense que cela dépend de la nature de la procédure stockée. Fondamentalement, vous devez gérer les erreurs si vous avez quelque chose à voir avec elles (ou les encapsuler pour les clients de la procédure) et les laisser se propager si vous n'avez rien à voir avec elles et ne pouvez pas le rendre plus convivial pour d'autres. couches de l'application.

Si la procédure stockée est conçue pour insérer des données brutes, je pense qu’elle devrait laisser l’application gérer les erreurs possibles. Si la procédure stockée est conçue comme une couche d'abstraction (et effectue une tâche spécifique au lieu d'exécuter une instruction spécifique ) et peut gérer l'erreur et en faire quelque chose. ou peut le signaler de manière gracieuse (par exemple, des codes d'erreur bien définis) à l'application, il devrait le faire. Sinon, il devrait incomber à l’application de s’assurer qu’elle n’insère pas de données en double, ni de la base de données (la base de données l’a déjà appliquée avec des clés primaires).

Afin d’être convivial, il est souvent recommandé de procéder à la sélection, et si l’enregistrement existe déjà, offrez à l’utilisateur la possibilité de le visualiser et / ou de le modifier.

Par exemple, si un utilisateur ajoute un nouvel enregistrement de client, il peut souhaiter consulter les informations déjà affichées pour ce client. Ils peuvent avoir des informations supplémentaires à ajouter à l'enregistrement, comme un numéro de téléphone.

Dans ce type de scénario, refuser d'ajouter l'enregistrement est moins utile qu'offrir la possibilité d'afficher le duplicata existant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top