Avatar billede jakobg Nybegynder
10. maj 2003 - 10:49 Der er 8 kommentarer og
1 løsning

Returnere ny IDENTITY fra SQL Server via dataadapater

Jeg ønsker indsætte en ny række i en simpel tabel i en SQL Server 2000 database, og skal umiddelbart derefter bruge dén værdi som SQL Server har givet den nye række i ID-feltet, som er et identity/primary key felt.

Tabellen, tbl_Test, indeholder kun to felter, og ser sådan ud:
ID (int, identity, autoincrement = 1)
strTitle (varchar(50)

Min VB.NET kode ser således ud:

'#########
dim cnnCon as new SQLClient.SQLConnection(strConn)
dim daData as new SQLClient.SQLDataAdapter("SELECT ID, strTitle FROM tbl_Test", cnnCon)
dim cbCmdBuilder as new SQLClient.SQLCommandBuilder(daData)

dim dsData as new DataSet()

daData.Fill(dsData, "tbl_Test")

dim rwRow as DataRow
rwRow = dsData.Tables("tbl_Test").NewRow()
rwRow.Item("ID") = 0
rwRow.Item("strTitle") = "Hello World"
dsData.Tables("tbl_Test").Rows.Add(rwRow)

daData.Update(dsData, "tbl_Test")
dsData.AcceptChanges()

trace.warn(rwRow.Item("ID"))
' #####
Og HER går det så galt: rwRow.Item("ID") indeholder stadigvæk 0 (nul), og selv hvis jeg ikke giver den nogen værdi før daData.Update(..) sker der heller ingenting.
Rækken bliver iøvrigt fint indsat i tabellen som forventet.

Normalt plejer jeg at lave alle INSERT statements via Stored Procedures, som slutter af med at returnere den nye ID-værdi, men det er desværre ikke en mulighed i det pågældende projekt (don't ask).
Fusk-løsninger med at slutte af med en SELECT MAX(ID) dur selvsagt heller ikke... :)

Så mit spørgsmål er følgende: Hvordan får jeg den SQL Server-tildelte primær nøgle værdi ud, når jeg indsætter data via et dataset og tilhørende dataadapter???

Jeg håber I kan hjælpe mig, på forhånd tak for hjælpen.
Avatar billede arne_v Ekspert
10. maj 2003 - 11:13 #1
Prøv med @@identity !

Fra SQLServer 7.0 online books:

Examples
This example inserts a row into a table with an identity column and uses @@IDENTITY to display the identity value used in the new row.

INSERT INTO jobs (job_desc,min_lvl,max_lvl)
VALUES ('Accountant',12,125)

SELECT @@IDENTITY AS 'Identity'

Altså jeg har aldrig brugt det og jeg har aldrig kode i VB.NET, men
umiddelbart virker det "interessant" !
Avatar billede jakobg Nybegynder
10. maj 2003 - 13:12 #2
Det er sådan jeg plejer at gøre når jeg anvender stored procedures til at indsætte data, men det kan somsagt ikke lade sig gøre i dette tilfælde.
Avatar billede arne_v Ekspert
10. maj 2003 - 13:15 #3
Kan VB.NET ikke sende SELECT statement afsted og læse det tal
der bliver returneret ?
Avatar billede arne_v Ekspert
10. maj 2003 - 13:17 #4
Det bør kunne lade sig gøre også selvom det ikke er en
stored procedure bare det er i samme connection.
Avatar billede jakobg Nybegynder
10. maj 2003 - 14:01 #5
Umiddelbart tror jeg ikke det er løsningen (eller om det overhovedet kan lade sig gøre).
Et dataset indeholder en slags disconnected kopi af dataene fra tabellen, og man kan foretage updates, inserts og deletes, for så til sidst at lave én batchupdate som commit'er data tilbage til databasen.
Det er altså ikke muligt i denne problemstilling at ligge noget logik på database-siden udover den fortløbende primærnøgle i tabellen.
Avatar billede arne_v Ekspert
10. maj 2003 - 14:44 #6
Muligt. Jeg kender som sagt ikke VB.NET - men var det ikke værd at prøve ?
Avatar billede arne_v Ekspert
10. maj 2003 - 15:15 #7
Og selvom det er en disconnected kopi af data, så må den enten
kommunikere det autoincremented numre til databasen eller
vente med at generere dem indtil de bliver committed, fordi ellers
kan den jo ikke garantere uniqueness.
Avatar billede jakobg Nybegynder
10. maj 2003 - 17:04 #8
Det er lige præcis hvad der sker: .NET-koden aner ikke en meter om hvilken værdi SQL Serveren har tænkt sig at tildele den FØR der bliver committed til databasen igen, hvis jeg eksempelvis angiver en værdi i ID-feltet, bliver det ignoreret når dataene bliver gemt og erstattet af en "rigtig" unik primærnøgle. Og det er hér mit spørgsmål bliver relevant, jeg forventede at rwRow.Item("ID") ville indeholde den tildelte værdi, men det gør den tilsyneladende ikke...
Avatar billede mads.rode Nybegynder
08. juni 2003 - 13:26 #9
Du skal være sikker på at det er den samme forbindelse du bruger. Update-funktionen åbner og lukker selv forbindelsen til databasen (cnnCon) hvis ikke den er åben i forvejen, men hvis den er det forbliver den også åben og du kan save din "SELECT @@IDENTITY AS 'Identity'".
Prøv sådan her.

cnnCon.Open();
Update();
AcceptChanges();
daData.Fill(dsData, "SELECT @@IDENTITY AS 'Identity'")
cnnCon.Close();

så tror jeg den er der.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester