probleem met serial
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
Serial? Neem aan dat je dus PostgreSQL gebruikt? Of Oracle? Of...
ik gebruik postgresql
nextval nextval functie kan je op voorhand de serial opvragen die toegewezen gaat worden.
Doormiddel van de 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
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
Dat werkt alleen als je je searchpad goed heb ingesteld, anders is het iets als nextval('schema.bestelnr').
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
nu krijg ik deze ?
cunces schreef op 28.12.2008 18:36:
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.@arjan: ERROR: could not open relation with OID 1
nu krijg ik deze ?
nu krijg ik deze ?
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.
Deze is overbodig want:
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 -
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?
Dit resultaat gaan fetchen en met id verder werken.
Jij hebt waarschijnlijk deze nodig:
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)
1
2
2
INSERT INTO bestellingen(klantid) VALUES (23) RETURNING id;
INSERT INTO bestelde_artikelen(id_bestelling, id_artikel) VALUES ($id, $artikel);
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 -
Bedankt voor de supergoede uitleg :)
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
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 -
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
In PostgreSQL zijn er de volgende niveau's te onderscheiden:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
- databasenaam
- schemanaam
- tabelnaam
- kolomnaam
- sequencenaam
- indexnaam
- etc.
- 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.
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!
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.