Oireet
Kun käytät joko SCOPE_IDENTITY()-tai@@IDENTITY-funktioita käyttäjätietosarakkeeseen lisättyjen arvojen noutamiseen, saatat huomata, että nämä funktiot palauttavat joskus virheellisiä arvoja. Ongelma ilmenee vain silloin, kun kyselyissä käytetään rinnakkaisia toimeenpanosuunnitelmia. Jos haluat lisätietoja siitä, miten voit selvittää, käyttävätkö kyselysi rinnakkaisia toimeenpanosuunnitelmia, katso seuraavan Microsoft-lataukset-osion kyselyjen rinnakkaisuusosiota:
Syy
Microsoft on varmistanut, että tämä on ongelma Microsoft-tuotteissa, jotka luetellaan tämän artikkelin alussa.
Ratkaisu
Kumulatiiviset päivitystiedot
SQL Server 2008 R2 Service Pack 1
Tämän ongelman korjaus julkaistiin ensimmäisen kerran SQL Server 2008 R2 Service Pack 1:n kumulatiivisen päivityksen 5 yhteydessä. Lisätietoja tämän kumulatiivisen päivityspaketin hankkimisesta saat napsauttamalla seuraavaa artikkelin numeroa, jolloin artikkeli on Microsoft Knowledge Base -tietokannassa:
2659694SQL Server 2008 R2 Service Pack 1:n kumulatiivinen päivityspaketti 5
HuomautusKoontiversiot ovat kumulatiivisia, koska jokaisessa uudessa korjausversiossa on kaikki hotfix-korjaukset ja kaikki aiemman SQL Server 2008 R2 -korjausversion sisältämät suojauskorjaukset. Suosittelemme, että harkitset tämän hotfix-korjauksen sisältävän uusimman korjausjulkaisun asentamista. Lisätietoja saat napsauttamalla seuraavaa Microsoft Knowledge Base ‑artikkelinumeroa:
2567616SQL Server 2008 R2 -koontiversiot, jotka julkaistiin SQL Server 2008 R2 Service Pack 1:n jälkeen
Vaihtoehtoinen menetelmä
Microsoft suosittelee, että et käytä kumpaakaan näistä funktioista kyselyissä, kun kyse on rinnakkaisista suunnitelmista, sillä ne eivät ole aina luotettavia. Käytä sen sijaan INSERT-lausekkeen OUTPUT-lausetta käyttäjätietojen hakemiseen alla olevassa esimerkissä esitetyllä tavalla.
Esimerkki OUTPUT-lauseen käyttämisestä:
DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key)
lisää @A arvoihin (1)
declare @B table (ID int primary key identity(1,1), B int not null)
lisää @B arvoihin (1)
valitse
[Rivimäärä] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
tilastoprofiilin määrittäminen
lisää _ddr_T
tuloste inserted.ID @MyNewIdentityValues
valitse
b.ID
kohteesta @A a
vasen liitos @B b b.ID = 1
left join @B b2 on b2. B = -1
vasen liitos _ddr_T t on t.T = -1
jossa ei ole (valitse * kohteesta _ddr_T t2, t2.ID = -1)
tilastoprofiilin määrittäminen pois käytöstä
valitse
[Rivimäärä] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY(),
[IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
valitse * @MyNewIdentityValues
siirry
Jos tilanteesi edellyttää jompaakumpaa näistä funktioista, voit kiertää ongelman jommankumman seuraavista menetelmistä.
Menetelmä 1:
Sisällytä seuraava vaihtoehto kyselyyn
OPTIO (MAXDOP 1)
Huomautus:Tämä voi vahingoittaa kyselyn SELECT-osan suorituskykyä.
Menetelmä 2:
Lue SELECT-osan arvo muuttujajoukkoon (tai yksittäiseen taulukkomuuttujaan) ja lisää kohdetaulukkoon MAXDOP=1. Koska INSERT-suunnitelma ei ole rinnakkaista, saat oikean semanttisen, mutta SELECT on rinnakkain halutun suorituskyvyn saavuttamiseksi.
Menetelmä 3:
Määritä rinnakkaisuusvaihtoehdon enimmäisaste arvoksi 1 suoritamalla seuraava lauseke:
sp_configure 'max degree of parallelism', 1
siirry
uudelleenmääritäminen ohituksen avulla
siirry
Huomautus:Tämä menetelmä voi heikentää palvelimen suorituskykyä. Tätä menetelmää ei tule käyttää, ellet ole arvioinut sitä testauksessa tai valmisteluympäristössä.
Lisätietoja
Microsoft Connect -virhe tässähttps://docs.microsoft.com/en-us/collaborate/connect-redirect
Rinnakkaisuusaste (MAXDOP) -https://msdn.microsoft.com/en-us/library/ms181007.aspx