Ik krijg niet wat ik wil hebben met Mysql

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ventilatiesysteem Productontwikkelaar HBO WO Verwa

Samengevat: Zij bieden flexibele ventilatiematerialen, geluidsdempers, rookgasafvoer producten en industrieslangen. Ben jij een technisch productontwikkelaar? Heb jij ervaring met het ontwikkelen van nieuwe producten? Vaste baan: Technisch Productontwikkelaar HBO WO €3.000 - €4.000 Zij bieden een variëteit aan flexibele ventilatiematerialen, geluiddempers, rookgasafvoer producten, industrieslangen en ventilatieslangen voor de scheepsbouw. Met slimme en innovatieve materialen zorgen wij voor een gezonde en frisse leefomgeving. Deze werkgever is een organisatie die volop in ontwikkeling is met hardwerkende collega's. Dit geeft goede ontwikkelingsmogelijkheden. De branche van dit bedrijf is Techniek en Engineering. Functie: Voor de vacature als Technisch Productontwikkelaar Ede Gld HBO WO ga

Bekijk vacature »

Christian Snijders

Christian Snijders

04/03/2022 21:01:23
Quote Anchor link
Hallo mede phphulper,

Nu ben ik al een tijdje het volgende aan het proberen met een script:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$kasquery = "and `date` like <= '".$_POST['jaar']."".$maand3."%'";
$query = "SELECT type, SUM(bedrag) FROM factuur_betalingen WHERE `afbij` = 'BIJ' AND (`type` = 'OVERSCHRIJVING' OR `type` = 'IDEAL' OR `type` = 'PIN') ".$kasquery." GROUP BY type";
$result = mysqli_query($link,$query) or die(mysqli_error());


Nu wil ik dus dat hij zoekt onder bijvoorbeeld 202203% of gelijk aan 202203%
Zoals ik hem nu ingevoerd heb werkt het niet, als ik het zo doe:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$kasquery = "and `date` <= '".$_POST['jaar']."".$maand3."%'";
$query = "SELECT type, SUM(bedrag) FROM factuur_betalingen WHERE `afbij` = 'BIJ' AND (`type` = 'OVERSCHRIJVING' OR `type` = 'IDEAL' OR `type` = 'PIN') ".$kasquery." GROUP BY type";
$result = mysqli_query($link,$query) or die(mysqli_error());


Neemt hij het niet tot de laatste mogelijkheid mee.

Heeft iemand een idee hoe ik dit werkend zal krijgen?

Alvast bedankt!
 
PHP hulp

PHP hulp

28/03/2024 09:20:17
 
- Ariën  -
Beheerder

- Ariën -

04/03/2022 21:07:52
Quote Anchor link
Echo je hele query eens.

Enne... Je bent vatbaar voor (onbedoelde) SQL-injection wat ook voor hacking kan worden misbruikt.
 
Christian Snijders

Christian Snijders

04/03/2022 21:21:33
Quote Anchor link
- Ariën - op 04/03/2022 21:07:52:
Echo je hele query eens.

Enne... Je bent vatbaar voor (onbedoelde) SQL-injection wat ook voor hacking kan worden misbruikt.


De query zit in een afgesloten gedeelte waar alleen ik bij kan, daarnaast is er vanuit de hostingprovider nog een en ander gedaan om injecties te voorkomen.

het lijkt hij laat bepaalde waarden weg waardoor de totaalstand niet klopt.
Je kan de sting van vandaag bijvoorbeeld zo zien: 20220304150311 daarvan hij alles pakken tot en met 202203 zolang het maar lager is dan 202204.
Maar als ik dus <= 202203% doe neemt hij niet alles uit de 202203% reeks mee.

Het enige wat mijn query doet is de waarden optellen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
while($row = mysqli_fetch_array($result)){
$inkomend = $inkomend + $row['SUM(bedrag)'];
}


Aangezien de query niet "dood" gaat weet ik ook niet precies wat ik in de query fout heb staan.
 
- Ariën  -
Beheerder

- Ariën -

04/03/2022 21:49:03
Quote Anchor link
Een injection kan ook onwetend gebeuren, dus ALTIJD escapen.

Laat je hele query eens zien zoals die uitgevoerd wordt?
 
Christian Snijders

Christian Snijders

04/03/2022 22:13:57
Quote Anchor link
- Ariën - op 04/03/2022 21:49:03:
Een injection kan ook onwetend gebeuren, dus ALTIJD escapen.

Laat je hele query eens zien zoals die uitgevoerd wordt?



dit is zoals hij staat hij telt waardes bij $inkomend en $uitgaand op.
Aan het einde van de rit hou ik dus $inkomend - $uitgaand over.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$kasquery = "and `date` <= '".$_POST['jaar']."".$maand3."%'";
$query = "SELECT type, SUM(bedrag) FROM factuur_betalingen WHERE `afbij` = 'BIJ' AND (`type` = 'OVERSCHRIJVING' OR `type` = 'IDEAL' OR `type` = 'PIN') ".$kasquery." GROUP BY type";
$result = mysqli_query($link,$query) or die(mysqli_error());

    while($row = mysqli_fetch_array($result)){

        $inkomend = $inkomend + $row['SUM(bedrag)'];
    
    }

$query = "SELECT type, SUM(bedrag) FROM factuur_betalingen WHERE `afbij` = 'AF' AND (`type` = 'OVERSCHRIJVING') ".$kasquery."";
$result = mysqli_query($link,$query) or die(mysqli_error());

    while($row = mysqli_fetch_array($result)){

        $uitgaand = $uitgaand + $row['SUM(bedrag)'];

    }

print "Resultaat: ".number_format($inkomend - $uitgaand,2);


dit staat boven de query:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if($_POST['kwartaal'] == '1e kwartaal'){
$maand1 = "01";
$maand2 = "02";
$maand3 = "03";
}
elseif($_POST['kwartaal'] == '2e kwartaal'){
$maand1 = "04";
$maand2 = "05";
$maand3 = "06";
}
elseif($_POST['kwartaal'] == '3e kwartaal'){
$maand1 = "07";
$maand2 = "08";
$maand3 = "09";
}
elseif($_POST['kwartaal'] == '4e kwartaal'){
$maand1 = "10";
$maand2 = "11";
$maand3 = "12";
}


Op die basis wordt dus de maand bepaald, meer dan dat doet het script ook niet.
Het is dus vreemd dat hij in feite alleen dit ziet: "202003"

Ik zou op 2,055.28 moeten komen en ik kom op: 2,190.77

Het lijkt er op dat hij alles na 202203 niks meer mee neemt.

Toevoeging op 04/03/2022 22:18:24:

Trouwens, wat is de beste manier tegen injecties beschermen is dat toevallig: mysql_real_escape_string()?

Toevoeging op 04/03/2022 22:35:07:

Het zal hem trouwens uitgaand moeten zitten, als ik nareken is het uitgaande van de reeks 202203% niet mee genomen

Toevoeging op 04/03/2022 22:38:20:

Voor inkomend is er trouwens nog geen record van 202203% dus het zit toch in beide het probleem.
Gewijzigd op 04/03/2022 22:36:14 door Christian Snijders
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/03/2022 23:10:31
Quote Anchor link
Je script deugt van geen kant als ik het mag zeggen.

- direct $_POST variabelen in je SQL is echt vragen om problemen.
- de maanden kun je met een eenvoudig sommetje berekenen als je het kwartaal weet.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
function maandenVanKwartaal($kwartaal)
{

    $eersteMaandVanHetKwartaal = $kwartaal * 3 - 2;
    return [$eersteMaandVanHetKwartaal++, $eersteMaandVanHetKwartaal++, $eersteMaandVanHetKwartaal];
}

?>

- .$maand3."%'" Dit is om overeenkomsten in tekst te zoeken in combinatie met de LIKE operator.

Bij datums werk je gewoon met < (kleiner dan) of > (groter dan).
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE `date` >= '2022-04-01' AND `date` < '2022-07-01'

Of je gebruikt BETWEEN maar dat is als het ware "tot en met" dus dan moet je iets hebben als
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE `date` BETWEEN '2022-04-01' AND '2022-06-30'

wat dan weer omslachtig is omdat je moet gaan achterhalen wat de laatste dag van de maand is (30 of 31 ?)

Om die datum teksten te maken zou je bijvoorbeeld een datetime object kunnen gebruiken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
// maak een nieuw DateTime object met de datum op 1 april 2022
$start = new DateTime('2022-04-01');

// maak nog een DateTime object welke afgeleid is van $start met daar opgeteld een Periode van 3 Maanden (P3M)
$end = $start->add(new DateInterval('P3M'));

$where = " WHERE `date` >= '" . $start->format('Y-m-d') . "' AND `date` < '" . $end->format('Y-m-d') . "'";
?>

- date is een gereserveerd woord in MySql. Er wordt aangeraden een andere benaming te kiezen. Dan hoef je ook geen backticks te gebruiken.

Ik ga er van uit dat je `date` kolom van het type DATE is?
Gewijzigd op 04/03/2022 23:21:47 door Frank Nietbelangrijk
 
Christian Snijders

Christian Snijders

04/03/2022 23:21:41
Quote Anchor link
Frank Nietbelangrijk op 04/03/2022 23:10:31:
Je script deugt van geen kant als ik het mag zeggen.

- direct $_POST variabelen in je SQL is echt vragen om problemen.
- de maanden kun je met een eenvoudig sommetje berekenen als je het kwartaal weet.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
function maandenVanKwartaal($kwartaal)
{

    $eersteMaandVanHetKwartaal = $kwartaal * 3 - 2;
    return [$eersteMaandVanHetKwartaal++, $eersteMaandVanHetKwartaal++, $eersteMaandVanHetKwartaal];
}

?>

- .$maand3."%'" Dit is om overeenkomsten in tekst te zoeken in combinatie met de LIKE operator.

Bij datums werk je gewoon met < (kleiner dan) of > (groter dan).
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE `date` >= '2022-04-01' AND `date` < '2022-07-01'


Om die datum teksten te maken zou je bijvoorbeeld een datetime object kunnen gebruiken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
// maak een nieuw DateTime object met de datum op 1 april 2022
$start = new DateTime('2022-04-01');

// maak nog een DateTime object welke afgeleid is van $start met daar opgeteld een Periode van 3 Maanden (P3M)
$end = $start->add(new DateInterval('P3M'));

$where = " WHERE `date` >= '" . $start->format('Y-m-d') . "' AND `date` < '" . $end->format('Y-m-d') . "'";
?>

- date is een gereserveerd woord in MySql. Er wordt aangeraden een andere benaming te kiezen. Dan hoef je ook geen backticks te gebruiken.


Ongetwijfeld is mijn code niet de mooiste, dat "date" heb ik al jaren geleden toegepast en is met de hoeveelheid records eigenlijk ook niet meer aan te passen anders had ik dat allang gedaan.

Daarnaast die "wildcard" (%) zo noem ik 'm maar even is omdat die "date" string langer is dan alleen Ymd, die bestaat dus uit YmdHis zoals het nu is is het: 20220304231911.
Ik deed dat er dus inzetten om te zorgen dat hij het laatste stukje hoe dan ook mee pakt, of is daar een manier voor om die alsnog op een andere wijze te omzeilen?

Ik wilde namelijk de database zo klein mogelijk maken jaren geleden waardoor ik dus de datum en tijd in één veld samenvoegde en later weer splitste.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/03/2022 23:24:26
Quote Anchor link
Waarom gebruik je dan niet gewoon het type DATETIME ?
 
Christian Snijders

Christian Snijders

04/03/2022 23:34:50
Quote Anchor link
Frank Nietbelangrijk op 04/03/2022 23:24:26:
Waarom gebruik je dan niet gewoon het type DATETIME ?


Toen ik dat jaren geleden toepaste had ik geen flauw benul wat ik deed "want het werkte".
toen mijn hostingprovider besloot mysql_query uit te sluiten en mysqli_query te verplichten kwam ik er ook achter dat veel dingen anders hadden gemoeten.

Ik heb alles (de query's) mezelf moeten aanleren, is niet altijd vlekkeloos gegaan.
Ben gewoon bang als ik nu kolom `date` omzet van VARCHAR(99) naar DATETIME dat het niet goed gaat komen en ik informatie zal verliezen.

maar als ik het dus goed begrijp snapt mysql "door mijn gebrabbel" in de code niet wat ik bedoel en stopt hij met tellen aan het begin van de "laatste kwartaalmaand" hij krijgt tenslotte als ik het goed begrijp de opdracht alles beneden "202203" mee te pakken in plaats van wat ik bedoelde.
Moet ik de query dan niet vertellen dat alles beneden de eerste maand van het volgende kwartaal mee moet pakken of denk ik dan te simpel?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

05/03/2022 00:35:44
Quote Anchor link
Je kunt het prima wijzigen alleen ga je natuurlijk eerst een kopie maken van je database op een test-server en daar maak je een migratie script welke je vervolgens uitvoerig gaat testen zodat wanneer je het op de productieserver draait het gewoon werkt zonder enig probleem. en natuurlijk zorg je ook dan altijd voor een backup.
 
Ad Fundum

Ad Fundum

05/03/2022 10:24:04
Quote Anchor link
In plaats van een volledige backup maken bij het wijzigen van een enkele kolom, kan je ook eerst een extra kolom maken in de tabel, die vullen met de omgezette waarden, en dan de oude kolom verwijderen.

Pseudocode:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
ALTER TABLE x ADD COLUMN nieuw DATETIME NULL DEFAULT NULL;
UPDATE x SET nieuw = STR_TO_DATE(oud, 'YmdHis');
-- ALTER TABLE x DROP COLUMN oud; -- pas uitvoeren als de nieuwe kolom klopt

Zie ook:
https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date
Gewijzigd op 05/03/2022 10:25:03 door Ad Fundum
 
Christian Snijders

Christian Snijders

05/03/2022 13:34:26
Quote Anchor link
Ik ben er inmiddels achter wat ik moest aanpassen om 202203% mee te pakken.
Ik heb het volgende gedaan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
AND (`date` <= '202203%' OR `date` LIKE '202203%')
nu geeft hij wel het resultaat wat ik vroeg.
Nu weet ik alleen niet of die % bij <= iets uithaalt of dat ik die maar gewoon weg moet halen.

Nu zal ik dus wel moeten werken aan het schoonmaken van de code zoals Frank zei met zijn "function", scheelt tenslotte ook een stuk code en dus minder belasting voor de webserver.

De VARCHAR ga ik niet meer aanpassen omdat ik dan alle codes door de website om moet bouwen aangezien het weer net anders werkt.

En betreft bescherming tegen SQL injecties, is mysql_real_escape_string() een oplossing om toe te passen? Zo ja: als ik die toepas moet ik die in de query zetten op deze manier?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE `date` LIKE '".mysql_real_escape_string($value)."'
(value is even een voobeeld)
 
- Ariën  -
Beheerder

- Ariën -

05/03/2022 14:00:59
Quote Anchor link
Ik zou ZEKER NIET de oude mysql_xxxx() functies gebruiken.

Zie ook:
mysqli_real_escape_string

(Ikzelf ben fan van de object-oriented versie van Mysqli.)
Gewijzigd op 05/03/2022 14:05:18 door - Ariën -
 
Christian Snijders

Christian Snijders

05/03/2022 14:12:00
Quote Anchor link
- Ariën - op 05/03/2022 14:00:59:
Ik zou ZEKER NIET de oude mysql_xxxx() functies gebruiken.

Zie ook:
mysqli_real_escape_string

(Ikzelf ben fan van de object-oriented versie van Mysqli.)

Daar was ik van op de hoogte ;-) aangezien ik al met mysqli werk maar had dit van internet af geplukt.
Daarnaast waarschuwt Apache al zodra ik dus mysql_query's uitvoer dat deze uit gefaseerd zullen worden.

Dus op welke manier kan ik hem dan het beste uitvoeren?
Even het "schaapvoorbeeld" erbij gehaald.

1:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$schaap = mysqli_real_escape_string('De string');
mysqli_query($link, "Select * WHERE `blaat` = '".$schaap."'");


2:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
mysqli_query($link, "Select * WHERE `blaat` = '".mysqli_real_escape_string($_POST['schaap'])."'");


Alvast bedankt voor de hulp tot nu toe :-)
Gewijzigd op 05/03/2022 14:12:26 door Christian Snijders
 
- Ariën  -
Beheerder

- Ariën -

05/03/2022 14:18:31
Quote Anchor link
Beide kan, ik raad aan om ze IN de query te plaatsen, zodat je altijd zeker bent dat het erin staat.

Maar vergeet de connectie argumente niet, check dus de manual.

Je kan ook kiezen voor prepared statements.
 
Ad Fundum

Ad Fundum

05/03/2022 20:04:54
Quote Anchor link
Christian Snijders op 05/03/2022 13:34:26:
Ik heb het volgende gedaan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
AND (`date` <= '202203%' OR `date` LIKE '202203%')
nu geeft hij wel het resultaat wat ik vroeg.

Je zal exact dezelfde resultaten hebben gekregen met
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
AND `date` LIKE '202203%'

Maar op jouw manier werkt het ook, en ik zou die ingewikkelde handleiding op de site van MySQL gewoon laten zitten.
Gewijzigd op 05/03/2022 20:07:26 door Ad Fundum
 
Christian Snijders

Christian Snijders

05/03/2022 20:30:46
Quote Anchor link
Ad Fundum op 05/03/2022 20:04:54:
Christian Snijders op 05/03/2022 13:34:26:
Ik heb het volgende gedaan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
AND (`date` <= '202203%' OR `date` LIKE '202203%')
nu geeft hij wel het resultaat wat ik vroeg.

Je zal exact dezelfde resultaten hebben gekregen met
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
AND `date` LIKE '202203%'

Maar op jouw manier werkt het ook, en ik zou die ingewikkelde handleiding op de site van MySQL gewoon laten zitten.


Ik moest beide toevoegen omdat alles voor 202203 en de huidige maand meegepakt moesten worden, doe ik alleen like '202203%' krijg ik alleen alles van deze maand.
 
Ivo P

Ivo P

05/03/2022 21:49:36
Quote Anchor link
AND (`date` <= '202203%'

is effectief gelijk aan

AND (`date` <= '202203YOHO'

Waarschijnlijk is het
AND (`date` <= '202203'

wat je zocht, maar dat pakt alles dt voor maart 2022 ligt. Dus ook dec 2014.

Maar "alles voor maart 2022 of in maart 2022" is wel gelijk aan "voor april 2022."

Maar het is wel heel jammer om geen datetime te gebruiken, inclusief alle handigheden die te vinden zijn in de datetime-functies.

Want een query "alles in een augustus van elk jaar" is nog te doen met like ____08%
maar alles van een dinsdag ga je niet gequery-t krijgen.
 
Christian Snijders

Christian Snijders

05/03/2022 23:18:52
Quote Anchor link
Ivo P op 05/03/2022 21:49:36:
volledige quote even geskipt..


Het was ook inderdaad de bedoeling alles voor april op te roepen en dat samen op te tellen, wat je zegt klinkt nu ook best logisch dat hij mijn query aanzag als "202203" en niet alles wat in 202203XX komt dus is eigenlijk alles lager laten zoeken dan 202204 logischer.

De hele bedoeling van mijn query is dus onbeperkt terug de tijd in gaan tot op het moment dat ik dat van hem vraag (in dit geval eind maart) er is dus geen begin of specifieke dag vereist.
 



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.