11
votes

Utilisation d'auto référencement dans SQL Server

insert into EMP values(12e2)

5 commentaires

Lorsque vous insérez la valeur 12E2 dans votre table EMP (et dans la colonne eid ), cette valeur existe alors la référence est satisfaite. ...


Il semble très étrange que vous feriez vous référencer de manière auto-référençant sur la même colonne ... cela n'a vraiment pas beaucoup de sens. En règle générale, ce que vous auriez, c'est Employee (ID INT, SPECTEURSTO INT) et que reportersto Colonne de référence auto-référence Employee (ID) que vous pourriez modéliser les employés -> les relations de patron. Mais auto-référençant sur la même colonne ..... Quel est votre scénario, que voulez-vous faire avec cela ???


@marc_s: Non monsieur. Je n'ai pas inséré 1200 à l'avance dans la table. Ou vous voulez dire que la contrainte FK après l'inséré de la ligne est insérée? Si oui, alors il vérifie que 1200 existe, et répondez est oui, donc cela réussit, mais cela poserait une double insertion?


Je viens d'essayer d'apprendre sur l'auto-référencement, alors essayez-le sur un exemple simple, c'est-à-dire sur une seule table de colonne


@marc_s, monsieur, est le fonctionnement de la clé étrangère comme ceci: sur le passage d'une requête d'insertion, SQL n'entraîne d'abord la valeur, puis la clé vérifie que si cette valeur existe dans la table parent, sinon, elle rentroie l'insert. Est-ce le fonctionnement du feed?


3 Réponses :


0
votes

Votre colonne FK fk_EMP_Eid permet probablement nulls, par conséquent, la relation n'a pas à exister, mais si vous essayez de mettre une valeur dans cette colonne, puis SQL Server vérifie que le FK est valide ou bien il erreur.


0 commentaires

12
votes

La colonne se réfère elle-même.

Ajout de la ligne elle-même garantit qu'il y a une ligne correspondante. Cette contrainte ne peut jamais échouer.

En fait en train de regarder le plan d'exécution SQL Server réalise ceci et ne gêne même pas la vérification. Il n'y a pas de assert opérateur présent.

plan

Si nous créons une table d'employés plus typique, il existe différents plans pour le Inserts pouvant enfreindre la contrainte comme ci-dessous. xxx

plan

si vous essayez plusieurs rangées a Bobine de blocage est ajouté au plan afin que les contraintes ne soient pas cochées avant que toutes les lignes soient insérées. xxx

 plan

et juste En complétude, il a été soulevé dans les commentaires, en regardant le cas lorsque l'insert est à une table avec un référencement FK un autre ... xxx

Dans cette instance, aucune bobine n'est ajoutée au plan qu'elle peut vérifier comme elle insère chaque ligne plutôt que tout à la fin afin qu'il puisse annuler plus tôt. Dans le cas où une ligne échoue (le résultat final sera le même)

plan


5 commentaires

La clé étrangère indique que si une valeur existe dans la table des parents, insérez cette valeur dans la table enfant, sinon pas. Donc, ici, la table des parents et de l'enfant est EMP. Il vérifie donc que 1200 existent dans la table des parents, la réponse n'est pas non plus, elle devrait donc échouer. Est-ce le travail?


@sqlchild - Il vérifie les contraintes sont remplies une fois les lignes insérées.


OK monsieur, donc lorsque lorsque les tables parent et enfant sont différentes, exemple: une table parent n'a pas d'enregistrement, puis sur l'insertion d'une valeur dans la table enfant, il insère d'abord la ligne de la table enfant, puis vérifie le parent. Tableau que si cette rangée existe, et ici, il ne l'a pas trouvé, donc cela reviendrait. ai-je raison monsieur?


@sqlchild - Yep, c'est correct. Dans ce cas, il peut vérifier car il insère des lignes plutôt que de tous à la fin, il peut donc récupérer plus tôt dans le cas où une ligne échoue (le résultat final sera le même)


@sqlchild: Le fait que la ligne soit réellement insérée avant que le parent ne soit recherchée puisse être facilement vérifiée si vous avez une colonne d'identité dans la table enfant. Vérifiez la valeur d'identité actuelle de la table enfant avant d'insérer ( Identif_Current ('Identifame') ), essayez ensuite d'insérer une ligne qui enfreint la clé étrangère, puis vérifiez la valeur de l'identité. Vous verrez qu'il a incrémenté, ce qui prouve que la rangée a été insérée, mais la transaction interne a été renvoyée en raison de la violation de la clé étrangère.



0
votes

J'ai créé cet exemple pour une clé de référence Auto pour MS SQL Server

CREATE TABLE Category (
   CategoryId int IDENTITY(1,1) not null,
   ParentId int null,
   CONSTRAINT PK_CategoryId PRIMARY KEY CLUSTERED (CategoryId),
   CONSTRAINT FK_ParentId FOREIGN KEY (ParentId) REFERENCES  Category(CategoryId),
   Title nvarchar(255) NOT NULL
);

insert into category(title)
values
('category1');

insert into category(title,parentid)
values
('category2',1);


0 commentaires