ID in query statement hoogste ID + 1

Status
Niet open voor verdere reacties.

sanders1969

Gebruiker
Lid geworden
29 dec 2018
Berichten
243
Onderstaande lukt niet omdat de id geen autonummering is en dus het getal 1 overneemt echter is id de primairy key dus wordt de record niet toegevoegd.
Kan ik iemand mij helpen deze SQL statement de hoogste id nummer op te vragen in optellen met getal 1?
Je kan op verschillende manier een record toevoegen echter wil ik het op deze manier weten.
Via een recordset of via een insert into waar je de waardes vooraf bepaalt is mij geheel duidelijk.
Ik verwacht iets met Max(id) +1 ofzo?

Code:
strSQL = "INSERT INTO tblTest (id, Tekst, Datum) SELECT id, Tekst, Datum FROM tblTest WHERE id=1"
CurrentDb.Execute strSQL, dbSeeChanges
 
Access heeft een paar nadelen, en één ervan is het ergerlijke gedrag om in nieuwe tabellen een sleutelveld toe te voegen (ja, Autonummering) met de volslagen idiote naam ID. Idioot, omdat elke nieuwe tabel die naam krijgt. Wat zeggen wij dus op dit forum? Gebruik zinvolle namen voor je sleutelvelden, maar niet “ID”. Wat heb je er aan om zo’n veld zelf als sleutelveld aan te maken, en dan geen Autonummering te gebruiken? Zo’n beetje van alle slechte opties de slechtste genomen :).

Kijken we naar je query, dan is het natuurlijk volslagen logisch wat er gebeurt: je gebruikt een INSERT om records toe te voegen die het ID 1 hebben. Moet je niet gek opkijken als je dan dat veld ook gaat vullen met die waarde.

De enige reden die ik kan bedenken om een sleutelveld zelf te vullen, is als je volledige controle over de opvolging van dat veld wilt hebben. Een veld FactuurID bijvoorbeeld wil je elk jaar opnieuw laten nummeren vanaf 1 (2019-001, 2019-002, 2020-001, 2020-002 etc). Daar gebruik ik altijd een functie voor, die je als Standaardwaarde op het veld zet. Daarmee krijg je automatisch in je formulier het juiste nieuwe nummer als je een nieuw record aanmaakt. Bij een Insert query gebruik je dan gewoon het veld op het actieve record in het formulier.
 
Dankje het is jammer genoeg niet zoals jij denkt maar de id naamgeving klopt alleen ik heb het bedacht.
Ik voeg eerst alles toe via een recordset echter wordt Access eruit gegooid als ie een veld tegenkomt decimal(11, 2)
Er hangt dus een SQL server database aan en sinds kort werkt de recordset niet meer.
Ik heb meerdere pogingen gewaagd en onderstaande code loopt ook vast als ie een veld tegenkomt welke decimal(11, 2) betreft.
En ja rsAdd.Fields(i - 1) = rs.Fields(i - 1) is gewaagd want eerst had ik veldnamen in een array geplaatst en daarna beide recordsets gevuld.
Ook de insert into gedaan maar ook daar werd Access eruit gegooid toen ik veld: decimal(11, 2) tegenkwam.
Misschien maak ik morgen een aparte functie waar ik via een dlookup de waarde van het veld opvraag, hopen dat ie niet over zn nek gaat als het een decimal(11, 2) betreft.

Code:
        lngMax2 = CurrentDb.TableDefs(strTableName).Fields.Count
        rsAdd.AddNew
        For i = 1 To lngMax2
            If Not IsNull(rs.Fields(i - 1)) Then rsAdd.Fields(i - 1) = rs.Fields(i - 1)
        Next i
        rsAdd.Fields("BEL_BED_ID_FK") = lngID1
        rsAdd.Fields("id") = DMax("id", strTableName) + 1
        rsAdd.Update
 
Ik snap het probleem niet; je hebt een veld ID dat nummers bevat. Verder een tekstveld en een datumveld. In een tekstveld is een komma nooit een probleem, een datum kent uiteraard geen komma's. Hoewel, tijden... :). Jouw probleem zit 'm denk ik niet in de procedure , maar in het feit dat je veld ID dus geen Long of Integer is, maar een veld met Decimalen. En omdat je upload naar een SQL server, moet je dan de Amerikaanse getalnotatie gebruiken, en dat is een punt, geen komma. Je zult dus getallen met een komma moeten omzetten naar een getal met een punt. Een sleutelveld met een decimaal is natuurlijk behoorlijk bagger, want als het hoogste nummer 123,65 is, dan ga je met jouw procedure vervolgens de nummers 124,65, 125,65, 126,65 etc genereren. Lijkt mij onwenselijk.
 
Hoi Octafish

Vergeet aub de eerdere code want daar gaat het niet om want tblTest was puur een voorbeeld om het simpel te houden.
Ik moet een record kopieren uit een dezelfde tabel echter als het veld van dat tabel een decimal(11, 2) betreft bijv: rsAdd.Fields("Bedrag") = rs.Fields("Bedrag") dan wordt Access eruit geknald.
Deze code heeft jaren gewerkt en opeens werkt het niet meer.
Lijkt alsof Office 365 een nieuwe update heeft ondergaan waardoor bestaande code nogmaals welke jaren probleemloos werkte en GEEN aanpassing heeft ondergaan opeen een cruciale bug oplevert.
Ik hoop dat je me begrijpt en zo niet, dan is het eenmaal zo want ik baal enorm want weet nu niet hoe ik records uit een eigen tabel kan kopieren zonder dat Access eruit wordt geknald.
Nogmaals insert into heb ik ook gebruikt maar zodra ik de waarde opvraag van decimal(11, 2) wordt Access eruit geknald.
Vandaar dat ik die ene query wilde gebruiken maar toen liep ik tegen het probleem aan dat er geen autonummering zit dus is ook geen optie.
 
Dag Sanders, als de BE een SQL server is, dan is de eenvoudigste oplossing: maak een sequence aan op de SQL server en dan kan je de waarde + 1 opvragen via de functie NEXT VALUE FOR .
https://docs.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver15

Je schrijft de insert als een SQL passs-through query in T-SQL en gebruikt de sequence via de NEXT VALUE FOR syntax. Het is een beetje gek om, als je over een SQL Server beschikt, de mogelijkheden van het systeem niet te gebruiken.
 
Het probleem kan ook aan de SQL Server kant zitten, al gebruikt Access nu wel een andere Engine, dus daar kan het heel goed aan liggen.
Je zou eens in deze richting kunnen denken:
Code:
 rsAdd.Fields("Bedrag") = CDbl(Replace(rs.Fields("Bedrag"),”,”.”))
Garantie tot aan de deur :).
 
Access wordt eruit geknikkerd wanneer Access de waarde van een veld: decimal(11, 2) via VBA inleest, zie afbeelding.
Ik kon net zien dat Access de waarde: "????" toonde toen ik met mijn muis over strWaarde2 bewoog.
Als ik de SQL statement in een query bekijkt kan ik wel de waarde van veld: decimal(11, 2) bekijken en zag ik waarde 100 staan.
We hadden eerst Windows Server 2008 draaien echter heeft mijn compagnon de server naar Windows Server 2013 gemigreerd, misschien dat het daarmee te maken heeft.
Een float levert geen problemen op en kan dus ook twee decimalen achter de komma hebben.
Een optie is om decimal(11, 2) te wijzigen naar een float echter staan er inmiddels veel data in en ik heb eerder gezien dat dit niet 1-2-3 lukt.
Ik begrijp echt niet waarom Access in VBA over zn nek gaat bij een veld: decimal(11, 2) en deze vooraf met een CDBL levert foutmelding 13 op omdat er een verkeerde waarde heeft om dit naar een Double te veranderen.
Misschien dat jullie nog een suggestie hebben anders blijft de enige optie om de velden: decimal(11, 2) te wijzigen naar een Float.
error_access.png
 
Ik zou soewieso eerst testen met de On Error inactief, zodat je kan zien waar hij de fout in gaat. Een getal in een string zetten mag natuurlijk wel, maar je gaat dan de teil in met terugschrijven. Behandel getallen altijd als getallen, als het verder niet uitmaakt. Desnoods maar je van strWaarde1 en strWaarde2 eerst Varianten, zodat je de waarde kunt controleren.
 
Ik zou zeker het veldtype niet aanpassen naar Float want dat is een benaderings datatype en geen precies datatype, dus 22.5 is niet noodzakelijk gelijk aan 22.5 in een ander veld. Als je het datatype wijzigt: ga dan naar numeric, dat is ook een vast precisie datatype, evenwaardig aan decimal.

Enkele vragen:
ALs je de tabelwaarden bekijkt, wordt het bedrag met de decimals dan correct weergegeven.
De definitie van je decimal is met 2 decimalen, probeer je daar ergens een getal met drie decimelen te gebruiken?
 
@Octafish ik begrijp je maar Access knalt er al gelijk uit dus maakt voor dit niet uit of ik een string of een double gebruik. Vaak doe ik even snel wat om te kijken of ik verder kom, maar lukt niet wat nogmaals ik word eruit gegooid.
En een integer met twee decimalen als veldtype is ook prima. De float werkt ook en foutloos.
@NoellaG: pfoe volgens mij werken we alleen met twee cijfers achter de komma maar durft het niet zeker te zeggen. Heb je een reden waarom je deze vraag stelt? De Float werkt ook met drie cijfers achter de komma. Heel vervelend want we moeten de tabellen geheel opnieuw doen incl de data want SQL server kan je niet veldtype zo maar wijzigen grrr...
 
dus maakt voor dit niet uit of ik een string of een double gebruik.
Een variant is geen van tweeën :). Ik lees juist berichten dat het heel goed is om getallen om te zetten naar Float, al was het maar omdat float een veel sneller datatype is dan decimal. Decimal wordt in SQL Server opgeslagen in 5 of 9 bytes. Float in 4 of 8 bytes. Computers rekenen in meervouden van 2 (4, 8 etc) dus een Float waarde is veel efficiënter en daarom ook sneller dan een Decimal. Float heeft ook geen invloed op de accuratesse van het getal, maar hooguit op het aantal cijfers achter de komma. Voor de weergave van een Float getal ben je dus iets meer afhankelijk van opmaak.
 
Thanks, dat wist ik niet dat deze sneller is. We zijn nu aan het testen wat in Access niet vastloopt.
Maar wist jij dat een veldtype: Decimal dat Access daar over zn nek gaat?
 
Access zelf kent óók een Numeriek veldtype met Veldlengte Decimaal. Dus daar zal hij niet over struikelen. Hooguit wellicht als de Decimal in je SQL server een andere betekenis heeft. Je zou wellicht een Pass-Through query kunnen gebruiken.
 
Voor degene die met SQl server verder willen: ik ben al meer dan 10 jaar DBA voor een grote, internationale firma en een float gebruik je alleen als je niet anders kan en de precisie van het getal niet belangrijk is. Een float is ook niet sneller. Dit is niet de plaats om een cursus te geven hoe SQL server werkt, maar wie meer wil weten kan naar mijn cursus komen, of de Microsoft cursus volgen.
Wat een decimal betreft: weet dat een decimal(10,5) voor SQL server een ander datatype is dan decimal(10,4)
 
Laatst bewerkt:
Hoi Octafish en NoellaG,

Ik heb een MS Access applicatie waar ik zo'n tien jaar in programmeer en is niet even om te zetten naar Dot.NET of een anders webomgeving.
Pass Through wil ik eens uitproberen maar ik heb veel lappen code met recordsets en is echt een hell of a job dit even dit te veranderen.
Ik wil jullie beide enorm bedanken voor het meedenken want het scheelt enorm als je weet dat twee senioren ook niet met een simpel te implementeren oplossing.
We zijn nu as we speak de database aan het aanpassen.
Wijze lessen allemaal ;-) en fijne avond!
 
als je dan toch met een passtrough werkt kan je het simpel oplossen door een procedure op SQL server aan te maken en deze aan te roepen, eventueel met als argument de ID die op een formulier actief is. Ik denk dat dit veruit de gemakkelijkste oplossing is.
 
Klopt en ik ga dit binnenkort eens uit zoeken.
Ooit in ergens jaar 2000 SQL Server 4 daagse training in Utrecht gevolgd.
Ik ga dit gauw es doorvoeren want ik ben ook met een ander applicatie bezig is die wordt retetraag.
Je kan toch ook sneller data ophalen of is het alleen maar records toevoegen via Pass Through?
 
je kan ook data opvragen. De snelheid hangt grotendeels af van welke indexen je hebt en hoe je deze gebruikt. Ook met de page filling kan je spelen, zowel in de data pagina's als de index pagina's.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan