Je connais les avantages de l'utilisation du CRUD, et certains inconvénients , mais j'aimerais get plus de commentaires d'experts et de conseils sur le process ci-dessous pour écrire des données dans une database, notamment sur les meilleures pratiques et avantages possibles.
J'ai rencontré deux methods de base de création de disques dans mon time en tant que développeur. Le premier (et généralement le less utile dans la plupart des travaux que j'ai vus) est de créer un talon et d'utiliser les différents champs peuplés (y compris le PK) partout où c'est nécessaire. Cela conduit généralement à une série d'loggings désaffectés flottant autour de la database sans but réel.
La seconde façon est de ne conserver qu'un seul bout en memory, donnant (ce qui serait) le champ PK de l'object une valeur par défaut de, par exemple, -1
pour représenter un nouvel logging. Cela réduit au minimum l'access à la database, surtout si l'logging n'est pas nécessaire plus tard.
Personnellement, j'ai trouvé la deuxième façon beaucoup plus pardonnante et directe que la première. La question que je voudrais poser, cependant, est de savoir s'il faut écarter CRUD en faveur d'une procédure stockée qui exécute à la fois les aspects INSERT
et UPDATE
du process CRUD basé sur la valeur par défaut mentionnée ci-dessus, quelque chose comme …
BEGIN IF @record_id = -1 INSERT .... ELSE UPDATE .... END
Tout commentaire serait apprécié.
En règle générale, j'ai tendance à écrire des procédures Upsert … mais j'ai basé la "correspondance" sur la contrainte unique, pas la key de substitution.
Par exemple.
dbo.Employee EmployeeUUID est le PK, le SSN de key de substitution est une contrainte unique.
dbo.uspEmployeeUpsert would look something like this: Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN ) Select NEWID() , LastName , FirstName , SSN from @SomeHolderTable holder where not exists (select null from dbo.Employee innerRealTable where innerRealTable.SSN = holder.SSN ) Update dbo.Employee Set EmployeeUUID = holder.EmployeeUUID , LastName = ISNULL ( holder.LastName , e.LastName ) /* or COALESCE */ , FirstName = COALESCE ( holder.FirstName , e.FirstName ) from dbo.Employee e , @SomeHolderTable holder Where e.SSN = holder.SSN
Vous pouvez également utiliser la fonction MERGE.
Vous pouvez également replace le SSN par SurrogateKey (EmployeeUUID dans ce cas)
Qu'est-ce que @SomeHolderTable vous request?
J'aime passer xml à la procédure stockée, la décomposer en une table @Variable ou #Temp, puis écrire la logique pour CU. D (elete) est également possible, mais je m'isole habituellement d'une procédure distincte.
Pourquoi est-ce que je le fais de cette façon?
Parce que je peux mettre à jour 1 ou 100 ou 1000 ou N loggings avec un coup de DB. Ma logique change rarement, et est isolée à un endroit.
Maintenant, il y a un petit coup de performance pour déchiqueter le Xml. Mais je trouve cela acceptable 99% du time. De time en time, j'écris une routine Upsert non basée sur un "set". Mais c'est pour de lourdes procédures de frappeur pour un usage intensif.
C'est ma prise.
Vous pouvez voir la partie "set based" de cette approche (avec l'ancienne syntaxe OPENXML) dans cet article:
http://msdn.microsoft.com/en-us/library/ff647768.aspx
Trouvez la phrase: "Effectuer des mises à jour et des insertions en bloc en utilisant OpenXML"
Voici la version "plus de code" de ce que l'URL ci-dessus parle:
http://support.microsoft.com/kb/315968
MODIFIER
if exists ( select 1 from dbo.Employee e where e.SSN = holder.SSN ) BEGIN Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN ) Select NEWID() , LastName , FirstName , SSN from @SomeHolderTable holder where not exists (select null from dbo.Employee innerRealTable where innerRealTable.SSN = holder.SSN ) END
Je ne ferais pas nécessairement cela. Mais c'est une option si vous voulez un "contrôle boolean".
Donc, avec ma configuration d'identificateur unique, je vais passer un "Guide vide" (00000000-0000-0000-0000-000000000000) (Guid.Empty en C #) à la procédure, quand je sais que j'ai un nouvel élément. Ce serait mon chèque "-1" dans votre scénario.
C'est une méthode, que vous pouvez vérifier pour un "si existe".
Cela dépend du nombre de mains que vous avez dans le pot.
Aussi, je n'ai pas mentionné que quand j'ai beaucoup de mains dans le pot, je vais détruire le xml ….. alors je vais faire un TRAN TRAN et COMMIT TRAN autour de mes déclarations CU (avec ROLLBACK dans là comme bien). De cette façon, mon UC est atomique, tout ou rien.
La fonction MERGE le fera également. Mais les avantages et les inconvénients de MERGE est un sujet différent.