Avatar billede mindplay Nybegynder
15. maj 2001 - 13:22 Der er 8 kommentarer og
1 løsning

ASP/ADO/MySQL - skaf autonøgle!??

I sin tid lærte jeg et lille trick, der virker bl.a. på Access databaser - man laver et recordset, åbner en tabel, kalder .AddNew, og indstiller så værdien af de felter man vil have gemt i sin nye record ... så kalder man .Update, og derefter kan man så aflæse værdien af et auto-increment felt (en autonøgle) - men jeg kan ikke få det samme til at fungere med MySQL. Jeg har noget i stil med:

  Dim X
  Set X = Server.CreateObject(\"ADODB.Recordset\")
  X.Open \"SELECT * FROM MinTabel\", Con, 1, 3
  X.AddNew
  X(\"Blah1\") = \"Blah blah\"
  X(\"Blah2\") = \"Blah blah\" \' <-- !!!
  X.Update
  MyKey = X(\"AutoKeyFelt\")

Det virkede med Access, det er sådan jeg plejer at gøre, men det virker som sagt ikke med MySQL ... jeg får allerede ved linien markeret med udråbstegn, flg. fejl:

Microsoft OLE DB Provider for ODBC Drivers error \'80040e21\'
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.

What\'s up with that?! HJÆÆÆLP! :)
Avatar billede alvion Nybegynder
15. maj 2001 - 14:28 #1
For det første: Brug IKKE \"recordset\" til indsættelse og opdatering af data i MySql, det kommer ikke til at give dig andet end bøvl (taler af erfaring)

Det du skal gøre her er følgende:

1) Indsæt din record via SQL
2) Aflæs det autonummererede felt via. SQL-kommandoen \"last_insert_id()\"

Set Con = Server.CreateObject(\"ADODB.Connection\")
Con.open(dsn-oplysninger)

sql = \"insert into MinTabel (blah1, blah2) values (\'hej med\', \'dig\')\"
con.execute(sql)

sql = \"select AutoKeyFelt from MinTabel where AutoKeyFelt = last_insert_id()\"
set rs = con.execute(sql)
MyKey = rs(\"AutoKeyFelt\")
set rs = nothing


Så spørger du sikkert, hvorfor ikke bare skrive den sidste SQL således:

sql = \"select last_insert_id() as AutoKeyFelt\"

Du kan jo prøve... og derefter konstatere, at det af en eller anden grund ikke virker
Avatar billede erikjacobsen Ekspert
15. maj 2001 - 14:58 #2
Ganske enig med alvion. ADO-metoderne dur ikke rigtig. Men jeg kan til
gengæld forklare hvorfor (det kan alvion måske også...)

Når du laver en \"SELECT * FROM mintabel\", får du jo den første post
tilbage i recordsættet. Det bruger ADO/ASP til at finde ud hvor store
felterne er.
    X(\"Blah2\") = \"Blah blah\"
Når du så får fejl i denne linie, er det så fordi feltet i \"Blah2\" er mindre
end 9 tegn, og det er det ASP brokker sig over. Så kan den for så vidt
være erklæret som char(255)....
Avatar billede alvion Nybegynder
15. maj 2001 - 15:14 #3
Jeg har bla. konstateret, at ADO ikke kan finde ud af de korrekte felttyper i forbindelse med opdatering, det er især TEXT felter, der giver problemer. Derudover kan ADO heller ikke finde ud af, hvilket felt, der udgør nøglen. Det har den konsekvens, at alle felter medtages i WHERE sætningen i forbindelse med en opdatering.

Laver du f.eks:

Set X = Server.CreateObject(\"ADODB.Recordset\")
X.Open \"SELECT * FROM MinTabel where AutoKeyFelt = 5\", Con, 1, 3
X(\"Blah1\") = \"Blah blah\"
X(\"Blah2\") = \"Blah blah\"
X.Update

hvor AutoKeyFelt er primærnøgle, så skulle man tro, at ADO omdanner det til:

update MinTabel set Blah1 = \'Blah blah\', Blah2 = \'Bla bla\' where AutoKeyFelt = 5

men istedet omdanner den det til:

update MinTabel set Blah1 = \'Blah blah\', Blah2 = \'Bla bla\' where (AutoKeyFelt = 5 and Blah1 = \'oprindelige-værdi\' and Blah2 = \'oprindelige-værdi\')

Det er jo fedt. Så hvis nu Blah2 er et LONGTEXT og en record indeholder 200KB tekst i feltet i forvejen, så tager det lidt tid at opdate den record...
Avatar billede alvion Nybegynder
15. maj 2001 - 15:15 #4
Jeg kendte ikke den forklaring du kom med erikjakobsen, men det forklarer faktisk et af de spørgsmål jeg aldrig har fået afklaret inden jeg holdt op med at bruge recordsets. Så tak for det :-)
Avatar billede alvion Nybegynder
15. maj 2001 - 15:16 #5
Jeg glemte i øvrigt at sige, at hvis der er flere felter i MinTabel end Blah1 og Blah2, så kommer de OGSÅ med i WHERE-sætningen - uanset om man har ændret dem eller ej.
Avatar billede mindplay Nybegynder
15. maj 2001 - 15:44 #6
alvion, du er lidt af en database-guru, er du ikke? :)

der er dog én ting, der bekymrer mig - hvis jeg først udfører en update, og derefter henter last_insert_id - risikerer jeg så ikke, at der i mellemtiden kan blive udført en anden SQL sætning ind imellem de to, og at jeg så får det forkerte id? eller er funktionen så intelligent, at den leverer det rigtige sidste id for hver forbindelse til databasen? ... giver det mening, det jeg spørger om??
Avatar billede erikjacobsen Ekspert
15. maj 2001 - 23:10 #7
Nej, det risikerer du netop ikke. Den der last_insert_id er knyttet til den
aktuelle forbindelse. Du må blot ikke lukke/genåbne forbindelsen inden du
spørger på den - men hvem ville også gøre det.
Avatar billede alvion Nybegynder
16. maj 2001 - 05:58 #8
mindplay >> :-) Det kan vi godt sige...
Avatar billede mindplay Nybegynder
16. maj 2001 - 10:31 #9
Jamen så siger jeg mange tak for hjælpen, til jer begge to! :)
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
Computerworld tilbyder specialiserede kurser i database-management

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