Avatar billede styrmand Nybegynder
02. oktober 2001 - 11:25 Der er 22 kommentarer og
1 løsning

Snedig løsning efterlyses

Jeg arbejder på en MS-Access Database gennem ADO. Når jeg opretter oposter i afhængige tabeller, har min programmering en tendens til at blive lidt kludret. Derfor efterlyser jeg nu en smartere løsning end den jeg anvender i dag.
Hvis man f.eks. skal oprette en faktura til en kunde, som ikke allerede eksisterer i systemet, skal kunden oprettes først, da fakturatabellen er afhængig (svag)af kundetabellen.
Det gør jeg med et SQLudtryk som \"Insert into Kunde...\". I kundetabellen har jeg et ID, som er et autonummer.
Problemet er nu, at jeg efterfølgende skal oprette en post i fakturatabellen, hvor det ny oprettede kunde-id indgår. Dette nummer får jeg ikke gennem min oprettelse og bliver derfor nødt til v.hj.a. endnu et sql-udtryk, at finde den nye kunde.
Det er ikke så smart, findes der ikke en mere elegant løsning.
NB!, jeg vil kun arbejde med tabeller som \"Set\", så komandoer, som rec.moveprevious m.v. duer ikke.

mvh

Stm

Avatar billede terry Ekspert
02. oktober 2001 - 11:32 #1
Well I think it sthe most logical method your using.
You could try another ilogical method.
Always attempt to INSERT the customer, if you get an error then the customer exists. If you dont then make your select to get the ID. (fewer operations) but not so logical!!
Avatar billede terry Ekspert
02. oktober 2001 - 11:33 #2
ilogical  = illogical
02. oktober 2001 - 11:33 #3
Hvis du kun vil benytte SQL udtryk til det hele (hvis jeg forstår det ret?) så får du et problem med at fange ID\'et. Hvis du deriod arbejdede med Recordsets, så ville du automatisk kunne trække ID\'et efter at du havde lavet en rec.update (endda før, hvis du arbejdede i ren Access)

HVorfor vil du ikke arbejde med recordsets?

/Thomas
Avatar billede styrmand Nybegynder
02. oktober 2001 - 11:46 #4
thomasJepsen> Der er flere årsager, som efterhånden bygger mere på erfaring og vane.
Men som jeg husker det, så er SQL langt mere effektiv og giver en hurtigere kode.
brug af Sql giver også en mere velstruktureret kode.
Brug af sql, sikrer mulighed for at skifte underliggende databasesystem.

Derfor.:-)
Avatar billede terry Ekspert
02. oktober 2001 - 11:51 #5
You can use Stored Procedures in Access 2000. So you can call a stored procedure with your \"faktura\" information and also the \"kunder\" information in one CALL. The stored procedure then decides if the customer exists or not and does what is necessary. Your code in your application, I assume ADP, is easier to read. But you need to do some more workk in Access.
Avatar billede terry Ekspert
02. oktober 2001 - 11:51 #6
ADP = ASP
Avatar billede proaccess Nybegynder
02. oktober 2001 - 11:55 #7
SELECT @@IDENTITY

Denne SQL giver dig det seneste Autonummer indsat i din database (på tværs af tabeller)...
Avatar billede terry Ekspert
02. oktober 2001 - 12:03 #8
Hi proaccess> I know this is availabale on other SQL databases but didnt know it was in Access!
Is it a new for Access 2000?
Is it for the connection, otherwise it can give problems, can\'t it?
Avatar billede styrmand Nybegynder
02. oktober 2001 - 12:06 #9
Terry> Det kræver dog stadig, at jeg skal formulere kriterier på kandidatnøgler (andre entydige feltkombinationer).
proAccess> Er den ikke lidt farlig? Jeg tænker på samtidige oprettelser, som kan bevirke, at en kunde får en andens faktura.
Avatar billede proaccess Nybegynder
02. oktober 2001 - 12:07 #10
It\'s new for Acc2000, and I\'m not sure of it\'s range, as Acc2000 is new to me... I havn\'t tested it yet, but it should be possible to use...
Avatar billede proaccess Nybegynder
02. oktober 2001 - 12:11 #11
>styrmand: Jo, det kan da godt være at man skal benytte den med måde...

Men ellers skal man, som du selv skriver, søge efter den pågældende kunde med selvstændig SQL-forespørgsel... (og det er der så ingen vej udenom)
Avatar billede styrmand Nybegynder
02. oktober 2001 - 12:16 #12
Jeg har faktisk lidt dokumentation af @@Identity fra Microsoft. Jeg kan klippe det ud og sende det hvis i er interesseret(ca. 1 A4).
Der står dog ikke noget om samtidighed.
Avatar billede terry Ekspert
02. oktober 2001 - 12:18 #13
styrmand>Ref: comment 12:06.31. I am not sure exactly what you mean here. Which other \"kriterier\" are you refering to?

Concerning Proaccess\'s SELECT @@IDENTITY. I would also think it should be possible. This and other things such as STORED PROCEDURES and VIEWS are new to Access 2000. I have read that they are there to support ADP (Access Data Projects) and the MSDE (Microsoft Data Engine) the later being a \"cut-down\" version of MS SQL. So I would think
SELECT @@IDENTITY works exactly as it does in MS SQL.


Avatar billede styrmand Nybegynder
02. oktober 2001 - 12:20 #14
Det fylder faktisk ikke mere end der kan være her. Så her følger det:

The @@IDENTITY variable

The @@IDENTITY variable is a global SQL variable that you can use to retrieve the last value used in a COUNTER data type column. You can\'t specify a table name when retrieving the @@IDENTITY variable. The value returned is always from the last table with a COUNTER field that had a new record added to it from code. Use the SELECT statement to retrieve the @@IDENTITY value.

SELECT @@IDENTITY

To add a value to the @@IDENTITY value, enclose the variable in square brackets.

SELECT [@@IDENTITY] + 1

Note  The @@IDENTITY variable listed in the previous SQL statements can be executed only through the Jet OLE DB provider and ADO; it will result in a value of 0 if used through the Access SQL View user interface. In addition, the variable is set only when records are inserted through programming code. If a record is inserted through the user interface, either with datasheets, forms, or SQL statements in the Access SQL View window, the @@IDENTITY variable will return 0. For this reason, the value of @@IDENTITY is only accurate immediately after adding a record from code.
Avatar billede styrmand Nybegynder
02. oktober 2001 - 12:29 #15
Terry> Det der gør min kode kompleks er, at jeg skal gennemføre 3 SQL udtryk for at oprette data i 2 tabeller.
Hvis jeg kunne få id fra den første oprettelse, behøvede jeg ikke at lave det andet SQL udtryk, som alene har til formål at finde den netop oprettede post.
For at gennemføre denne søgning, er det nødvendigt at opbygge et kriterium, som man er 100% sikker på giver et entydigt svar (un-ambigious answer, tror jeg nok det er på engelsk:-)
Opbygning af dette kriterium, kan være kompliceret og desuden er det en oplagt fejlkilde.
Det er derfor jeg gerne vil slippe for dette udtryk.

Jeg tror dog jeg vil prøve at opbygge en test, som viser hvordan @@identity arbejder, med flere samtidige oprettelser.
Avatar billede styrmand Nybegynder
02. oktober 2001 - 12:55 #16
Nu har jeg gennemført testen og den viser at @@identity arbejder på tværs af brugere.
Så den er ikke sikker at bruge.

Er det ikke muligt at lave en Stored Procedure, som indsætter en ny post og returnerer postens ID?
Avatar billede terry Ekspert
02. oktober 2001 - 13:00 #17
Well the ID would again be either from @@identity or you would have to SELECT it. So you still havent made things easier.
Th eway you origianlly do it sounds fine, I think it may be just a case of structuring your code.
Make a function for creating a customet and another for getting customer the ID.
If you have it all in one procedure then it will be a bit \"kludret\".



Avatar billede styrmand Nybegynder
02. oktober 2001 - 13:48 #18
Ang. @@identity, var jeg vist nok lidt for kategorisk, da jeg afviste den.
Min test var forkert, og de tests jeg har lavet efterfølgende, indikerer at den måske kan anvendes.
Jeg tør dog ikke bruge den, da jeg ikke er helt sikker på mine tests.
Hvis der er nogen der finder yderligere information, vil jeg gerne høre om det.
Avatar billede styrmand Nybegynder
02. oktober 2001 - 13:58 #19
Jeg har fundet et link her, som påstår, så vidt jeg kan læse det, at identity inden for samme connection ikke påvirkes af andre connections.

http://support.microsoft.com/support/kb/articles/Q232/1/44.ASP
Avatar billede terry Ekspert
02. oktober 2001 - 14:04 #20
Sounds great!
Avatar billede proaccess Nybegynder
02. oktober 2001 - 14:15 #21
Man kunne eventuelt udvidde med lidt transaktions-styrring:

Public Function testTRANSACTION()
  \'CurrentProject.Connection.Execute \"CREATE TABLE ProAccess1 (ID IDENTITY CONSTRAINT PrimaryKey PRIMARY KEY, Navn VARCHAR(50))\"
  \'CurrentProject.Connection.Execute \"CREATE TABLE ProAccess2 (ID Long, Tidspunkt DATETIME, TEST IDENTITY CONSTRAINT PrimaryKey PRIMARY KEY)\"
  CurrentProject.Connection.Execute \"BEGIN TRANSACTION\"
  CurrentProject.Connection.Execute \"INSERT INTO ProAccess1 (Navn) VALUES (\'ProAccess\')\"
  CurrentProject.Connection.Execute \"INSERT INTO ProAccess2 (ID, Tidspunkt) VALUES (@@IDENTITY, Now())\"
  CurrentProject.Connection.Execute \"COMMIT TRANSACTION\"
End Function

Bemærk de 2 første linier bruges til at oprette tabeller, og skal derfor kun køres første gang !!!
Avatar billede styrmand Nybegynder
01. november 2001 - 00:24 #22
Jeg havde glemt den her. Men det var vel PRoAccess, som kom nærmest.
Avatar billede proaccess Nybegynder
01. november 2001 - 08:34 #23
Takker ;-)
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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