Toon posts:

[MySQL] Insert en Update in één query?

Pagina: 1
Acties:
  • 184 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik ben bezig met een forum en nu heb ik voor het toevoegen van een bericht twee qeuries. Het gaat om de volgende queries.

1:. INSERT INTO posts VALUES ('', '{ID}', '{USER}', '{TIME}', '{MESSAGE}')
2:. UPDATE topics SET replies=replies+'1', lastpost='{TIME}' WHERE id='{ID}'

Ik heb al wat pogingen ondernomen om ze samen te voegen. Daarnaast kan ik ook niet op de MySQL site vinden of dit wel kan.

Het forum is in PHP gemaakt, voor zover dat uitmaakt :?.

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 31-08 10:19

D2k

nee :)

Doet iets met Cloud (MS/IBM)


  • judgem
  • Registratie: December 2001
  • Laatst online: 28-04-2014

judgem

Lord of Metal

Wel toch? Lijkt mij een kwestie van een dubbele hidden value toevoegen...

Topicstarter: In welke taal heb je je forum geschreven?

* judgem is ook maar een beginner..

- Ik bespreek ook harde waren en dan wel op www.lordsofmetal.nl - en ik draai en programmeer ze in DYNAMO


Verwijderd

judgem schreef op 25 augustus 2002 @ 15:39:
Wel toch? Lijkt mij een kwestie van een dubbele hidden value toevoegen...

Topicstarter: In welke taal heb je je forum geschreven?

* judgem is ook maar een beginner..

1) Volgens mij snap je het probleem niet
2) Taal maakt niet uit, het gaat hier gewoon om het samenvoegen van twee queries in MySQL

... en dat samenvoegen gaat gewoon niet, dus gewoon twee queries uitvoeren.

Verwijderd

Topicstarter
Dat was eigenlijk niet het antwoord waar ik op zat te wachten :'(.

Dan wil ik bij deze een andere vraag stellen: "Hoe kan ik controleren of de UPDATE/INSERT query is gelukt? Zodat ik nooit maar één van de queries uitvoer waardoor foute statistieken zouden ontstaan."

  • Neman
  • Registratie: September 2000
  • Laatst online: 30-08 12:47

Neman

Een uit de lucht gegrepen naam

Verwijderd schreef op 25 augustus 2002 @ 15:41:
Dat was eigenlijk niet het antwoord waar ik op zat te wachten :'(.

Dan wil ik bij deze een andere vraag stellen: "Hoe kan ik controleren of de UPDATE/INSERT query is gelukt? Zodat ik nooit maar één van de queries uitvoer waardoor foute statistieken zouden ontstaan."
Gewoon kijken of mysql_query() true of false returnt (in het geval van PHP).

Verwijderd

Topicstarter
Die functie geeft toch geen boolean door, maar een MySQL resource? Dit zou in het geval van een INSERT/UPDATE query altijd een lege waarde zijn toch?

  • MichelVH
  • Registratie: Oktober 2001
  • Laatst online: 01-08 09:33
Als de query gelukt is krijg je een MySQL-resource terug. Bij een mislukte query krijg je false terug.

Don't be afraid of the dark, be afraid of what it hides


Verwijderd

Database transacties zijn je antwoord. Hoewel deze nog niet uitgebreid getest zijn in MySQL. Je hebt max-binary nodig van een hogere 3.23.x versie of de standaard binary van de alpha versie 4.x
Of je kunt natuurlijk zelf compilen met --with-innodb. Maar de meeste isp's die MySQL ondersteuning hebben nog geen versie die transacties ondersteunt (mede door de expirimentele status).

Kenmerk van een transactie is dat hij de veranderingen alleen voor de connectie waarbinnen de transactie zich afspeelt registreerd, en alle veranderingen in 1 keer op commando naar de schijf wegschrijft zodat het ook voor anderen zichtbaar is.

voorbeeld in pseudo code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//mysql pseudo code

query "SET AUTOCOMMIT=0"
query "BEGIN"
query "INSERT ..."
if insert_failed         //check of de query gelukt is en of het het gewenste resultaat had
    //insert niet gelukt: terugdraaien
    query "ROLLBACK"
    query "SET AUTOCOMMIT=1"
else
    //insert gelukt ga verder
    query "UPDATE ..."
    if update_failed     //idem als bij insert_failed
        //update niet gelukt draai alles terug (ook insert)
        query "ROLLBACK"
        query "SET AUTOCOMMIT=1"
    else
        //alles gelukt, schrijf naar schijf
        query "COMMIT"
        query "SET AUTOCOMMIT=1"


Nogmaals, MySQL is neit de meest geschikte dbms hiervoor, ik zou een 'echte' dbms nemen. Maar daarbij is het idee erachter hetzelfde, alleen kun je bij die dbmssen de "SET AUTOCOMMIT" querys vaak achterwege laten.

zie ook: http://hotwired.lycos.com.../tutorials/tutorial2.html

edit:

Gratis 'echte' DBMS-en zijn Postgresql (open-source), Sybase Adaptive Server (Een oudere versie is gratis down te loaden voor linux), Interbase (Een oudere versie is ooit eens opensourced, CVS tree is nog steeds opensource) en Firebird (Een fork van interbase)

Verwijderd

offtopic:
Als je een forum in ASP had gemaakt had ik je zo kunnen helpen :P
Ik heb namelijk 2 dagen geleden ook een forum gemaakt, maar dan niet in php. en ik heb zoiets wat jij nu zoekt gemaakt, maar dan in ASP :P
/me pwnz yoo!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

De waarde's die je nu in je db opslaat zijn redundant. Dit betekent dat ze er dubbel in staan. Je hoeft ze er dus niet in te zetten, maar op deze manier maak je je queries wel wat sneller. Als je bang bent dat het mis gaat kun je altijd nog een 'herstel' script draaien. Hierin tel je gewoon de reacties en zoek je de laatste tijd op en insert je dit gewoon in je topic tabel. Dit scriptje kun je vervolgens op een rustig moment draaien en al je data klopt weer.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Verwijderd schreef op 25 augustus 2002 @ 22:11:
Nogmaals, MySQL is neit de meest geschikte dbms hiervoor, ik zou een 'echte' dbms nemen.
Ik zou het graag willen doen. Voor mij zelf is het geen probleem om ff Oracle/PostgreSQL of iets dergelijks te installeren, maar ik ben het forum niet voor eigen gebruik aan het maken, maar voor gratis uitgave zoals phpBB, OpenBB etc. Dus MySQL is dan absoluut een vereiste.
Janoz schreef op 25 augustus 2002 @ 23:33:
Als je bang bent dat het mis gaat kun je altijd nog een 'herstel' script draaien. Hierin tel je gewoon de reacties en zoek je de laatste tijd op en insert je dit gewoon in je topic tabel. Dit scriptje kun je vervolgens op een rustig moment draaien en al je data klopt weer.
Het is misschien wel iets om in het administratie paneel te verwerken. Of bij elke 1000 pageviews ofzo. Dat lijkt me nu de beste oplossing :).

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Verwijderd schreef op 25 augustus 2002 @ 15:29:
Ik ben bezig met een forum en nu heb ik voor het toevoegen van een bericht twee qeuries. Het gaat om de volgende queries.

1:. INSERT INTO posts VALUES ('', '{ID}', '{USER}', '{TIME}', '{MESSAGE}')
2:. UPDATE topics SET replies=replies+'1', lastpost='{TIME}' WHERE id='{ID}'

Ik heb al wat pogingen ondernomen om ze samen te voegen. Daarnaast kan ik ook niet op de MySQL site vinden of dit wel kan.

Het forum is in PHP gemaakt, voor zover dat uitmaakt :?.
Het is wel mogelijk, maar je hebt wel een aantal beperkingen waar je niet op heen kan. dmv van gebruik van de REPLACE Statement.

Je hebt alleen een aantal nadelen:
- De update gaat over de hele row, dus velden die je niet mee update wordt veranderd in de default waarde.
- Je kan geen calculaties maken die betrekking hebben op de vorige waarde. Dit werkt bv niet SET replies=replies+1

Programmer - an organism that turns coffee into software.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Ook dat werkt niet LuCarD. Het gaat hier om een wijziging van 2 apparte tabellen, en dat is (iig in mysql) niet mogelijk.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Janoz schreef op 26 augustus 2002 @ 10:47:
Ook dat werkt niet LuCarD. Het gaat hier om een wijziging van 2 apparte tabellen, en dat is (iig in mysql) niet mogelijk.
Oops.... niet goed gelezen...

dacht dat het om dezelfde tabel ging...


:(

Programmer - an organism that turns coffee into software.


Verwijderd

Ik snap waarom je mysql wilt gebruiken.

In het artikel van deze link staat hoe je transacties kunt simuleren in een db systeem dat het niet support, zoals access en oudere MySQL versies... Hoewel je dit beter niet voor kritische zaken (zoals geldzaken enzo) kunt gebruiken is het voor een forum wel goed genoeg denk ik. Omdat je niet met concurrency zaken te maken hebt.

http://php.weblogs.com/mysql_transactions

  • JaQ
  • Registratie: Juni 2001
  • Laatst online: 22:19

JaQ

daemian>> de nieuwere versies van mysql hebben een transactie systeem. Let wel even op dat de performance veel lager komt te liggen dan.
edit:
maar je zei ook oudere versies van mysql.. beter lezen dus. *schaam*


topicstarter>> Als je graag transacties wilt gebruiken, kijk dan eens naar postgresql. Die kent transacties en een procedural language (procedures op db niveau dus) Postgresql is ook gratis, dus komt ook in aanmerking. De procedural language lijkt verdacht veel op het pl/sql dat oracle gebruikt, dus als je daar een beetje ervaring in hebt, kan je dat vrij snel oppikken (en een lading functionaliteit op db-niveau afvangen ;) )

Egoist: A person of low taste, more interested in themselves than in me


  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Verwijderd schreef op 25 augustus 2002 @ 15:41:
Dan wil ik bij deze een andere vraag stellen: "Hoe kan ik controleren of de UPDATE/INSERT query is gelukt? Zodat ik nooit maar één van de queries uitvoer waardoor foute statistieken zouden ontstaan."
Volgens mij is dit het enige wat jij zoekt: mysql_affected_rows

On track


Verwijderd

WouZz schreef op 26 augustus 2002 @ 14:04:
[...]


Volgens mij is dit het enige wat jij zoekt: mysql_affected_rows
En hoe wilde je dan de eerste query terugdraaien als de tweede mislukt?

Verwijderd

Topicstarter
Verwijderd schreef op 26 augustus 2002 @ 14:17:
[...]


En hoe wilde je dan de eerste query terugdraaien als de tweede mislukt?
Met mysql_insert_id() waarschijnlijk. Alleen ik ben niet echt een voorstander van deze "ranzige" manier van programmeren.

Verwijderd

Goed stel je voor je INSERT m, vervolgens klapt de dbms er uit of er is een te grote load, updaten gaat niet, maar deleten vervolgens ook niet meer. Met een transactie die niet gecommit is zal de insert ook niet naar de schijf geschreven zijn.

Als je het zonder transactie doet is waarschijnlijk de manier op php.weblogs.com (zie link boven) het best, het verdient geen schoonheidsprijs (je gebruikt eigenlijk omgekeerde referentiele integriteit)
het principe komt er op neer: je doet eerst je updates en vervolgens je insert, al je selects uit de upgedate tabel join je met de tabel waarin je insert, op die manier worden alleen de waardes gelezen waarbij je code tot helemaal bij insert is gekomen. Je tabel waarin je updates zitten raakt als het vaak fout gaat erg vol met corrupte data, maar dat is een kwestie van eens in de zoveel tijd een delete uitvoeren op de records waarop de join false levert.

Zoals ik zei het is eigenlijk tegen alle relationele regels in, maar mysql is toch al niet echt relationeel en het is beter dan hopen dat je achteraf nog kunt deleten. En het gaat 'maar' om een forum en niet besturing van kernwapens ;-)
Pagina: 1