[SQL] Probleem met 'autonummering'

Pagina: 1
Acties:

  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
Ik heb de volgende query:

SQL:
1
2
INSERT INTO facturen(factuurnr, bla bla bla) 
VALUES((SELECT (MAX(factuurnr) +1) FROM facturen), bla bla bla);


Nu is het probleem echter dat als de tabel facturen leeg is, MAX(factuurnr) null is en de query niet uitgevoerd kan worden.
Is het mogelijk om dit af te vangen en dan er een 1 van te maken in de query of moet dit afgevangen worden in de software?

De database draait op PostgreSQL.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Kent deze database niet iets van een IsNull functie?
Maar heeft PostgreSQL geen autonumber of identity? :?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
gorgi_19 schreef op 10 October 2003 @ 12:28:
Kent deze database niet iets van een IsNull functie?
Maar heeft PostgreSQL geen autonumber of identity? :?
Er is wel een IS NULL functie maar hoe pas je dit toe in de query?
En volgens mij heeft PostgreSQL geen autonumber...

  • Freee!!
  • Registratie: December 2002
  • Laatst online: 21-08 09:58

Freee!!

Trotse papa van Toon en Len!

Als dit meerdere keren geïmplementeerd moet worden, kun je natuulijk direct bij het aanmaken van de tabel een eerste record erin zetten met een door jou te bepalen factuurnummer (0 lijkt me wel handig), waarna het vermelde SQL-statement wel goed loopt.

The problem with common sense is that sense never ain't common - From the notebooks of Lazarus Long

GoT voor Behoud der Nederlandschen Taal [GvBdNT


  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
Mr. Liu schreef op 10 October 2003 @ 12:35:
Als dit meerdere keren geïmplementeerd moet worden, kun je natuulijk direct bij het aanmaken van de tabel een eerste record erin zetten met een door jou te bepalen factuurnummer (0 lijkt me wel handig), waarna het vermelde SQL-statement wel goed loopt.
Dat kan inderdaad, maar als het anders kan wil ik het graag anders :)

  • Sircuri
  • Registratie: Oktober 2001
  • Niet online

Sircuri

Volledig Appelig

postgresql heeft geen auto_numbering zoals je zou kennen uit MySQL. Zoals elke SQL-dialect heeft ook PostgreSQL een soort auto_nummering. Dit heet een SEQUENCE in PostgreSQL en een GENERATOR in bijvoorbeeld Interbase.
Ik zou als ik jou was ook gebruik maken van zo'n sequencer of generator. Zoals je het nu gemaakt hebt, is totaal niet betrouwbaar. Wat als er tegelijk met de SELECT een INSERT gedaan wordt door nog een ander proces? Dan klopt jouw MAX select niet meer, want er zijn ondertussen nieuwe toegevoegd.

Signature van nature


  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
Sircuri schreef op 10 oktober 2003 @ 12:39:
postgresql heeft geen auto_numbering zoals je zou kennen uit MySQL. Zoals elke SQL-dialect heeft ook PostgreSQL een soort auto_nummering. Dit heet een SEQUENCE in PostgreSQL en een GENERATOR in bijvoorbeeld Interbase.
Ik zou als ik jou was ook gebruik maken van zo'n sequencer of generator. Zoals je het nu gemaakt hebt, is totaal niet betrouwbaar. Wat als er tegelijk met de SELECT een INSERT gedaan wordt door nog een ander proces? Dan klopt jouw MAX select niet meer, want er zijn ondertussen nieuwe toegevoegd.
Daarvoor is de uitvoerende methode (java) synchronized 8)
Maar ik zal eens kijken naar dat sequence gebeueren...

  • Freee!!
  • Registratie: December 2002
  • Laatst online: 21-08 09:58

Freee!!

Trotse papa van Toon en Len!

Sircuri schreef op 10 oktober 2003 @ 12:39:
[...]
Ik zou als ik jou was ook gebruik maken van zo'n sequencer of generator. Zoals je het nu gemaakt hebt, is totaal niet betrouwbaar. Wat als er tegelijk met de SELECT een INSERT gedaan wordt door nog een ander proces? Dan klopt jouw MAX select niet meer, want er zijn ondertussen nieuwe toegevoegd.
Als het om afscherming gaat, dat zet je dat INSERT statement toch gewoon tussen een LOCK* <table> en een UNLOCK* <table> statement.


*Exacte terminologie kan per database verschillen


EDIT:
Te laat

[ Voor 4% gewijzigd door Freee!! op 10-10-2003 12:44 ]

The problem with common sense is that sense never ain't common - From the notebooks of Lazarus Long

GoT voor Behoud der Nederlandschen Taal [GvBdNT


  • Sircuri
  • Registratie: Oktober 2001
  • Niet online

Sircuri

Volledig Appelig

ok, ik wist natuurlijk niet dat je met java bezig was :P al geeft dat natuurlijk geen garantie dat een ander niet tegelijk kan schrijven in de database.
Succes in ieder geval

Signature van nature


  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
Sircuri schreef op 10 October 2003 @ 12:44:
ok, ik wist natuurlijk niet dat je met java bezig was :P al geeft dat natuurlijk geen garantie dat een ander niet tegelijk kan schrijven in de database.
Succes in ieder geval
Als je het goed programmeert is dat aardig nauwkeurig te bepalen dacht ik zo :)
Maar goed, in elk geval bedankt voor de tip!

Verwijderd

Je kan een nvl gevruiken in het select gedeelte.

code:
1
2
3
4
5
6
7
8
INSERT INTO facturen
  ( factuurnr
  , bla bla bla
  ) 
VALUES
  ( (SELECT ( NVL(MAX(factuurnr),0) +1) FROM facturen)
  , bla bla bla
  );


Als factuurnr NULL is wordt de waarde 0 gebruikt. Daar wordt dan 1 bij opgeteld.

  • Hatsekie_D
  • Registratie: April 2002
  • Laatst online: 14-07 17:45

Hatsekie_D

Doe mij maar een glaasje prik

Topicstarter
Verwijderd schreef op 10 October 2003 @ 12:54:
Je kan een nvl gevruiken in het select gedeelte.

code:
1
2
3
4
5
6
7
8
INSERT INTO facturen
  ( factuurnr
  , bla bla bla
  ) 
VALUES
  ( (SELECT ( NVL(MAX(factuurnr),0) +1) FROM facturen)
  , bla bla bla
  );


Als factuurnr NULL is wordt de waarde 0 gebruikt. Daar wordt dan 1 bij opgeteld.
Helaas:
ERROR: Function nvl(bigint, integer) does not exist Unable to identify a function that satisfies the given argument types You may need to add explicit typecasts


edit:
Oplossing gevonden:
Bij het zoeken naar documentatie over de NVL-functie kwam ik de COALESCE functie tegen. Die werkt wel, op de hierboven beschreven manier.

[ Voor 14% gewijzigd door Hatsekie_D op 10-10-2003 13:47 ]

Pagina: 1