probleem met serial

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Cunces v

cunces v

28/12/2008 17:25:00
Quote Anchor link
Ik heb 2 tabellen: bestelbonnen & bestelbonnen_produkten.

Als een klant een produkt koopt maak ik een nieuwe bestelbon aan (tenzij die gebruiker nog een bestelbon heeft die nogniet betaald is, dan wordt hij daar toegevoegd) Oké dus ik heb enkel een probleem in geval 1 (nieuwe bestelbon maken)


Dan doe ik een insert in bestelbonnen (bestelnr(maar die geef ik niet in vanwege een serial), username)

om dan die bestelbon te linken aan produkten gebruik ik de tabel bestelbonnen_produkten waar ik het volgende inzet (bestelnr, produktnr, aantal)

Maar het probleem is dus: wanneer ik een nieuwe rij wil toevoegen aan bestelbonnen_produkten weet ik niet welke bestelnr ik moet gebruiken aangezien ik dat bij de creatie niet heb ingegeven (serial loste dat op voor me).
Heeft iemand hier een oplossing voor?



edit: nja ik weet dat het beperkt is maar tis maar opdracht voor school & heb geprobeerd het zo goed mogelijk uit te leggen ^^


edit: postgresql uiteraard
Gewijzigd op 01/01/1970 01:00:00 door Cunces v
 
PHP hulp

PHP hulp

05/11/2024 14:49:45
 
Arjan Kapteijn

Arjan Kapteijn

28/12/2008 17:33:00
Quote Anchor link
Serial? Neem aan dat je dus PostgreSQL gebruikt? Of Oracle? Of...
 
Cunces v

cunces v

28/12/2008 18:15:00
Quote Anchor link
ik gebruik postgresql
 
Arjan Kapteijn

Arjan Kapteijn

28/12/2008 18:17:00
Quote Anchor link
Doormiddel van de nextval nextval functie kan je op voorhand de serial opvragen die toegewezen gaat worden.
 
Robert Deiman

Robert Deiman

28/12/2008 18:18:00
Quote Anchor link
@cunces

Beetje raar misschien om zomaar items aan een onbetaalde bon toe te voegen? Je kan hier toch beter meerdere "losse" bestelling van maken, als dat besteld wordt buiten een andere bestelling om.

Waarom? Omdat je nu het risico loopt dat betalingen door elkaar gaan lopen, je maakt het jezelf ongelovelijk lastig door bestellingen er aan toe te voegen.

Stel:
- Ik koop eerst 3 producten met een totaalbedrag van E 51,33
- Voordat deze betaald zijn plaats ik nog een bestelling (a E 32,55) , maar je betaling is al onderweg (de acceptgiro of weet ik veel wat is al verzonden a 51,33)
- Deze bestelling zet jij bij die andere in, maw ik krijg een factuur van E 83,88
- Plaats ik nog een bestelling, wordt de facturatie hoger, terwijl in de tussentijd best een deel betaald kan zijn.

Je kan nu wel zeggen hoeveel er in euro's van een bestelling (in totaal) is geplaatst, maar een klant kan niet zomaar zien welke bestellingen teglijk zijn gedaan door hem/ haar.

Ik zou persoonlijk er voor kiezen er wel een losse bestelling van te maken. De totale bedragen van iemand kan je heel eenvoudig in SQL bij elkaar optellen.
Gewijzigd op 01/01/1970 01:00:00 door Robert Deiman
 
Cunces v

cunces v

28/12/2008 18:24:00
Quote Anchor link
ik probeer

select nextval(bestelnr) from bestelbonnen maar dan krijg ik:
ERROR: column "bestelnr" does not exist


ken je mss een klein voorbeeldje geven?


edit: even robbert ze comment aan het lezen
Gewijzigd op 01/01/1970 01:00:00 door cunces v
 
Arjan Kapteijn

Arjan Kapteijn

28/12/2008 18:30:00
Quote Anchor link
Dat werkt alleen als je je searchpad goed heb ingesteld, anders is het iets als nextval('schema.bestelnr').
 
Cunces v

cunces v

28/12/2008 18:32:00
Quote Anchor link
@robert: zal even m'n volledige tabel posten.


create table bestelbonnen(

bestelnr serial NOT NULL,
gebruikersnaam varchar(50) not null,
prijs integer, //nuja integer moet noch floating point worre ofzo maar dat laat ik even erbuiten
betstatus char(15),
levstatus char(15),
bestellingsnota text,

constraint primaire_sleutel_bestellingen primary key (bestelnr),
constraint verschillende_bestelnummers unique(bestelnr),
constraint toegestane_waarden_betaalstatus check (betstatus in ('Betaald','Niet betaald','Zendprobleem')),
constraint toegestane_waarden_leverstatus check (levstatus in ('Verstuurd','Niet verstuurd','Leverprobleem')),
constraint bestellingen_gebruikersnaam_vreemde_sleutel foreign key (gebruikersnaam)
references gebruikers(gebruikersnaam)

)
WITHOUT OIDS;
al de grants






Het attribuut betaald zal ervoor zorgen dat hetgeen jij wilt, niet zal lukken (hoop ik! correct me if I'm wrong ajb :))
Dus wat denk je van de opbouw? is die solide?


edit: zou nog een date misschien moeten bijzetten..
Gewijzigd op 01/01/1970 01:00:00 door cunces v
 
Cunces v

cunces v

28/12/2008 18:36:00
Quote Anchor link
@arjan: ERROR: could not open relation with OID 1

nu krijg ik deze ?
 
Frank -

Frank -

28/12/2008 19:04:00
Quote Anchor link
cunces schreef op 28.12.2008 18:36:
@arjan: ERROR: could not open relation with OID 1

nu krijg ik deze ?
En hoe ziet jouw query eruit? Zonder deze query kunnen wij alleen gaan raden waarom het fout gaat, dat wordt dus niets. Geef dus even relevante informatie.

Ps. Er is niet voor niets een handleiding geschreven, de handleiding van PostgreSQL is één van de betere handleidingen in deze wereld, daar staat het antwoord op jouw probleem ook vast wel in.

Pps.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
constraint verschillende_bestelnummers unique(bestelnr),

Deze is overbodig want:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
constraint primaire_sleutel_bestellingen primary key (bestelnr),

doet al exact hetzelfde. Daarnaast levert een serial altijd een uniek nummer op, jouw uniek-constraint is dan ook een beetje dubbel-dubbel-op.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
 
Cunces v

cunces v

29/12/2008 10:03:00
Quote Anchor link
select nextval(schema1.bestelbonnen.bestelnr) from schema1.bestelbonnen
ook bij
select nextval(bestelbonnen.bestelnr) from schema1.bestelbonnen

als bij

select nextval(bestelnr) from schema1.bestelbonnen

krijg ik dezelfde fout.

@pgFrank: ja idd nu jet zegt :)

Iemand een oplossing?
 
Frank -

Frank -

29/12/2008 10:41:00
Quote Anchor link
Een sequence staat niet in een tabel, het is een apart object in de database. Er kan dus onmogelijk een FROM worden gebruikt. Daarnaast staat in de handleiding haarfijn uitgelegd dat je de naam van de sequence tussen quotes moet zetten wanneer je NEXTVAL() gebruikt. Ook dat mist in jouw queries.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
SELECT
  NEXTVAL('schemanaam.sequencenaam') AS id;

Dit resultaat gaan fetchen en met id verder werken.

Jij hebt waarschijnlijk deze nodig:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
SELECT
 NEXTVAL('bestelbonnen.bestelnr') AS new_bestelnr;

Ga na het fetchen met new_bestelnr aan de slag, die krijg je retour.

Ps. Het datatype SERIAL is eigenlijk een BIGINT samen met een SEQUENCE. Een SERIAL maakt deze automatisch aan, maar je zou ze ook zelf met het handje aan kunnen maken. Er is bij een SERIAL dus eigenlijk geen sprake van een datatype, maar van een domain.

Pps. Wel éérst het volgende bestelnummer opvragen en dan pas alle INSERTs (inclusief dit nummer!!!) gaan uitvoeren. Wellicht is het handiger om RETURNING te gebruiken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
INSERT INTO bestellingen(klantid) VALUES (23) RETURNING id;
INSERT INTO bestelde_artikelen(id_bestelling, id_artikel) VALUES ($id, $artikel);

Waarbij $id dus het id is dat je van RETURING retour hebt gekregen. Dit werkt sinds versie 8.2 en scheelt je weer een SELECT-query.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
 
Cunces v

cunces v

29/12/2008 11:13:00
Quote Anchor link
Bedankt voor de supergoede uitleg :)
 
Cunces v

cunces v

29/12/2008 17:19:00
Quote Anchor link
SELECT
NEXTVAL('bestelbonnen.bestelnr') AS new_bestelnr;

geeft ERROR: schema "bestelbonnen" does not exist


dan heb probeerde ik SELECT
NEXTVAL('"Schema1".bestelbonnen.bestelnr') AS new_bestelnr;

werkt ook niet.. E
RROR: cross-database references are not implemented: "R3Vandev.bestellingen.bestelnr"


http://www.postgresql.org/docs/7.3/static/functions-sequence.html#FUNCTIONS-SEQUENCE-TABLE

ze geven niet meer mogelijkheden :s

Iemand die een oplossing heeft voor m'n probleem?
Gewijzigd op 01/01/1970 01:00:00 door cunces v
 
Frank -

Frank -

29/12/2008 17:28:00
Quote Anchor link
En hoe heet jouw schema dan wel? Of heb je geen specifiek schema aangemaakt? In dat geval gebruik je blijkbaar "public".

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
SELECT
  NEXTVAL('public.bestelnr') AS new_bestelnr;

Maar waarom doe je niets met de foutmeldingen? Daar staat letterlijk in wat het probleem is: schema "bestellingen" does not exist

Bestaat dus niet. Wanneer "bestellingen" jouw database is, weet je dus dat dit niet het schema is, het is tenslotte de database.

Waar je Schema1 vandaan haalt, is mij een raadsel. Het zegt ook niks, een schema is een schema en 1 is maar een nummertje waar je verder niets mee kunt.

Ps. Waarom voer je dit soort queries niet even uit in pgAdmin3 ? Dan weet je binnen 3 tellen of een query wel of niet werkt, daar doe je echt niet de hele dag over.

Pps. Jij weet hoe jouw schema heet, wij kunnen daar alleen maar naar raden. Vul dan gewoon even de juiste naam in, zo moeilijk kan dat niet zijn.
Gewijzigd op 01/01/1970 01:00:00 door Frank -
 
Cunces v

cunces v

29/12/2008 17:34:00
Quote Anchor link
nja maar die bestellingen (ik verander al m'n tabelnamen altijd als ik ze online post & ben deze vergete te wijzigen, heb vorige post wel gewijzigd) tabel bestaat dus wel degelijk.


bij een select moet ik ook doen select * from "schema1".tabelnaam
dus deze zou denk ik de juiste moeten zijn.
NEXTVAL('"Schema1".bestelbonnen.bestelnr') AS new_bestelnr;

maar dan krijg ik dus die cross-database shit
 
Frank -

Frank -

29/12/2008 18:07:00
Quote Anchor link
Een database is geen schema, je kunt dus onmogelijk foutmeldingen krijgen cross-database gebruik wanneer je met een schema bezig bent.

In PostgreSQL zijn er de volgende niveau's te onderscheiden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
- databasenaam
  - schemanaam
    - tabelnaam
      - kolomnaam
    - sequencenaam
    - indexnaam
    - etc.

Een sequence is een object binnen een schema en heeft NIETS met een tabel te maken. Een sequence staat op hetzelfde niveau als een tabel of een index.

'"Schema1".bestelbonnen.bestelnr'

Wat moet dit voorstellen? Dit kan alleen maar "database" - "schema" - "sequence" zijn, andere opties zijn er niet. 1 van deze 3 namen hoort daar dus niet te staan en jij weet exact welke dat is, jij hebt de boel aangemaakt. In de functie NEXTVAL() zet je de schemanaam samen met de naam van de sequence.

3 vragen:
1) Wat is de naam van jouw database?
2) Wat is de naam van het schema waar in je aan het werk bent?
3) Wat is de naam van de sequence die je probeert aan te roepen?

Wanneer pgSQL zelf de sequence heeft aangemaakt, zal er waarschijnlijk iets van _seq in de naam van de sequence voorkomen. Bij mijn weten maakt pgSQL er altijd "tabelnaam_kolomnaam_seq" van, bv. "test_id_seq".

Ps. Mocht je zelf voor de naam "Schema1" hebben gekozen, deze naam slaat nergens op. Bedenk een naam die ergens op slaat, die beschrijft wat er in het schema staat. Doe je dat niet, bereid je dan maar vast voor op de nodige bugs. Je gaat gegarandeerd de fout in met Schema2 of Schema3, nog een paar kansloze namen.
 
Cunces v

cunces v

29/12/2008 18:26:00
Quote Anchor link
het werkt eindelijk! ik had dus sql zelf de sequentie laten aanmaken & dus heb ik met "tabelnaam_kolomnaam_seq" ipv altijd gewoon de kolomnaam gewerkt! Zo simpel is het ! :')

sorry voor het rare gedoe maar u moet begrijpen dat ik het nog aan het leren ben eh ^^

Maar soit, stel uw hulp enorm op prijs!
 
Frank -

Frank -

29/12/2008 18:39:00
Quote Anchor link
Graag gedaan! Mits je voortaan dat "u" en "uw" maar weglaat...

Er is niets mis met leren en van je fouten leer je. Je gebruikt toch wel pgAdmin3 om je database te beheren? Daarin zie je ook de sequences als aparte objecten staan en zie je snel en eenvoudig de verschillende namen staan. Kan het nooit meer fout gaan.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.