{"id":1226,"date":"2015-09-06T17:07:40","date_gmt":"2015-09-06T15:07:40","guid":{"rendered":"http:\/\/www.sqlserver.fr\/blog\/?p=1226"},"modified":"2020-09-01T10:07:51","modified_gmt":"2020-09-01T08:07:51","slug":"identity-pourquoi-lui-tourner-le-dos","status":"publish","type":"post","link":"https:\/\/www.sqlserver.fr\/blog\/identity-pourquoi-lui-tourner-le-dos\/","title":{"rendered":"@@IDENTITY : Pourquoi lui tourner le dos &#8230;"},"content":{"rendered":"<p>Malgr\u00e9 sa pr\u00e9sence dans de nombreux scripts, la valeur syst\u00e8me @@IDENTITY est \u00e0 mon sens \u00e0 proscrire. Je vais chercher \u00e0 d\u00e9montrer dans ce petit papier pourquoi et par quoi la remplacer.<!--more--><\/p>\n<p>En reprenant l&rsquo;<a href=\"https:\/\/docs.microsoft.com\/fr-fr\/sql\/t-sql\/functions\/identity-transact-sql\" target=\"_blank\" rel=\"noopener noreferrer\">aide en ligne<\/a>, il est indiqu\u00e9 que @@IDENTITY retourne \u00ab\u00a0la derni\u00e8re valeur d&rsquo;identit\u00e9 ins\u00e9r\u00e9e.\u00a0\u00bb. Jusqu&rsquo;ici, tout semble normal.<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1241\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo1.png\" alt=\"Demo1\" width=\"393\" height=\"473\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo1.png 393w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo1-249x300.png 249w\" sizes=\"auto, (max-width: 393px) 100vw, 393px\" \/><\/a><\/p>\n<p>Mais en y regardant de plus pr\u00eat, et surtout en lisant entre les lignes, on peut trouver certaines cas dans lesquels ont n&rsquo;a pas tout \u00e0 fait ce \u00e0 quoi on pourrait s&rsquo;attendre.<\/p>\n<p>Par exemple, consid\u00e9rons le cas d&rsquo;insertion dans une table avec un d\u00e9clencheur. L&rsquo;aide en ligne nous indique clairement que, si le d\u00e9clencheur lui-m\u00eame fait des insertions, ce sont ces derni\u00e8res qui risquent d&rsquo;\u00eatre prises en compte.<\/p>\n<pre class=\"brush: sql; gutter: false; first-line: 1\">CREATE TABLE TableAvecTrigger(Id int IDENTITY, Valeur varchar(max))\r\nGO\r\nCREATE TABLE TableTrace(Id int IDENTITY, Texte varchar(max))\r\nGO\r\nCREATE TRIGGER TR_Test ON TableAvecTrigger FOR INSERT\r\nAS\r\nBEGIN\r\n\tSET NOCOUNT ON\r\n\tinsert into TableTrace (Texte) values ('D\u00e9but Trace');\r\n\tinsert into TableTrace (Texte) select 'Insertion de ' + Valeur from inserted\r\n\tinsert into TableTrace (Texte) values ('Fin Trace');\r\nEND\r\nGO<\/pre>\n<p>A ce moment-l\u00e0, les valeurs retourn\u00e9es par @@IDENTITY ne correspondent pas du tout aux valeurs des instructions INSERT principales &#8230;<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1242\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo2.png\" alt=\"Demo2\" width=\"479\" height=\"459\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo2.png 479w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo2-300x287.png 300w\" sizes=\"auto, (max-width: 479px) 100vw, 479px\" \/><\/a><\/p>\n<p>On voit ici que les valeurs des derniers identifiants techniques retourn\u00e9s ne correspondent pas \u00e0 la table que l&rsquo;on est en train de remplir, mais sont en fait biais\u00e9s du fait de l&rsquo;action du d\u00e9clencheur, qui impacte lui aussi une table avec une colonne IDENTITY.<\/p>\n<p>La solution \u00e0 ce probl\u00e8me se nomme <a href=\"https:\/\/docs.microsoft.com\/fr-fr\/sql\/t-sql\/functions\/scope-identity-transact-sql\" target=\"_blank\" rel=\"noopener noreferrer\">SCOPE_IDENTITY<\/a>. Cette instruction permet de retourner la derni\u00e8re valeur d&rsquo;IDENTITY ins\u00e9r\u00e9e, mais en se limitant \u00e0 l&rsquo;\u00e9tendue\u00a0courante. De fait, l&rsquo;action du d\u00e9clencheur, qui est dans une autre \u00e9tendue, n&rsquo;a pas d&rsquo;impact.<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1243\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo3.png\" alt=\"Demo3\" width=\"472\" height=\"462\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo3.png 472w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2015\/09\/Demo3-300x294.png 300w\" sizes=\"auto, (max-width: 472px) 100vw, 472px\" \/><\/a><\/p>\n<p>En conclusion, \u00e9vitez absolument le @@IDENTITY, et remplacez-le syst\u00e9matiquement par SCOPE_IDENTITY(), \u00e0 moins bien entendu que vous cherchiez vraiment \u00e0 obtenir des r\u00e9sultats \u00ab\u00a0sp\u00e9ciaux\u00a0\u00bb &#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Malgr\u00e9 sa pr\u00e9sence dans de nombreux scripts, la valeur syst\u00e8me @@IDENTITY est \u00e0 mon sens \u00e0 proscrire. Je vais chercher \u00e0 d\u00e9montrer dans ce petit papier pourquoi et par quoi la remplacer.<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1226","post","type-post","status-publish","format-standard","hentry","category-article_sql"],"_links":{"self":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/1226","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/comments?post=1226"}],"version-history":[{"count":17,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/1226\/revisions"}],"predecessor-version":[{"id":1816,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/1226\/revisions\/1816"}],"wp:attachment":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/media?parent=1226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/categories?post=1226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/tags?post=1226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}