Could someone please assist / advise on what I could do in order to make the last four search fields / inputs optional (along with AND statements) in the SQL query?
I have tried the code below but it doesn't seem to make the last four fields optional:
public static function findBySearch($location, $category, $type, $bedrooms, $bathrooms, $minamount, $maxamount)
{
$db = static::getDB();
$sql = 'SELECT * FROM posts
WHERE location = :location
AND category LIKE :category
AND type LIKE :type
AND
(:bedrooms IS NULL OR bedrooms = :bedrooms)
AND
(:bathrooms IS NULL OR bathrooms = :bathrooms)
AND
(:minamount IS NULL OR amount >= :minamount)
AND
(:maxamount IS NULL OR amount <= :maxamount)';
$stmt = $db->prepare($sql);
$stmt->bindValue(':location', $location, PDO::PARAM_STR);
$stmt->bindValue(':category', $category, PDO::PARAM_STR);
$stmt->bindValue(':type', $type, PDO::PARAM_STR);
$stmt->bindValue(':bedrooms', $bedrooms, PDO::PARAM_INT);
$stmt->bindValue(':bathrooms', $bathrooms, PDO::PARAM_INT);
$stmt->bindValue(':minamount', $minamount, PDO::PARAM_INT);
$stmt->bindValue(':maxamount', $maxamount, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_CLASS, get_called_class());
return $result;
}
Related
Sorry for the confusing question, I'm a beginner looking for some improvements to my code.
What I'm currently trying to do is "Linking" a mysql value to another.
Here's an example :
I'm creating a PHP-based fight
There is a database named "fightm" which contains important informations
Some of the informations are the ATTACKS and the COOLDOWN
I want to simplify my code by having ATTACK and COOLDOWN linked together
To clarify, I'll give you some code (Don't forget that I'm a beginner, if this is bad written you can correct me)
if (isset($_POST['fdd_attackbas1']) AND ($infomonstre["fightm_cdbas1"] < 1)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
fightm_cdfuite=GREATEST(0, fightm_cdfuite - 1),
fightm_cdbas1=(fightm_cdbas1 + 1),
fightm_cdbas2=GREATEST(0, fightm_cdbas2 - 1),
fightm_cdbas3=GREATEST(0, fightm_cdbas3 - 1),
fightm_cdrare1=GREATEST(0, fightm_cdrare1 - 1),
fightm_cdrare2=GREATEST(0, fightm_cdrare2 - 1),
fightm_cdultime=GREATEST(0, fightm_cdultime - 1)
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
if (isset($_POST['fdd_attackbas2']) AND ($infomonstre["fightm_cdbas2"] < 1)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
fightm_cdfuite=GREATEST(0, fightm_cdfuite - 1),
fightm_cdbas1=GREATEST(0, fightm_cdbas1 - 1),
fightm_cdbas2=(fightm_cdbas2 + 1),
fightm_cdbas3=GREATEST(0, fightm_cdbas3 - 1),
fightm_cdrare1=GREATEST(0, fightm_cdrare1 - 1),
fightm_cdrare2=GREATEST(0, fightm_cdrare2 - 1),
fightm_cdultime=GREATEST(0, fightm_cdultime - 1)
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
As you can see, i'm repeating myself for each "attack". Now, imagine that I have more than 20 attacks ! That would be insane.
What i would like to do is something this way (THE CODE I WANT BUT WITH COMMENTS FOR THE CODE PARTS I DON'T KNOW)
if (isset(//One of the attack//) AND (// The CD linked to the attack //)) {
$query = $db->prepare('UPDATE users SET vieac=(vieac - :damage ) WHERE username=:username');
$query->bindValue(':username', $username, PDO::PARAM_INT);
$query->bindValue(':damage', $damage, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
$query = $db->prepare('UPDATE fightmonster SET
fightm_life=(fightm_life - :atqb),
fightm_dmgperso=:atqb,
fightm_dmgenemy=:damage,
// COOLDOWN PART, SAME BUT WITHOUT NEEDING TO CHANGE //
WHERE player_id =:id');
$query->bindParam(':id', $donnees['id'], PDO::PARAM_INT);
$query->bindValue(':damage', $degatreduiteffet, PDO::PARAM_INT);
$query->bindValue(':atqb', $atkboosteffet, PDO::PARAM_INT);
$query->execute();
$query->CloseCursor();
header("Refresh:0");
exit();
}
This would be very helpful, but I can't understand how it can be done.
Thanks you and sorry for the long text !
Restructure your code into a foreach loop like this:
$keys = ['fdd_attackbas1', 'fdd_attackbas2', ..];
foreach ($keys as $key) {
if (isset[$key] && ..) {
..
exit();
}
}
So I have a rather big form that is used to update the database. I am having trouble now with this block of code that inserts data from a form. Previously it was working but I changed the form to show "open" transactions so a user knows which transaction number to close. Now I get syntax/access violations. Rtransid is the key, if anyone was wondering. Thanks for any help.
//If there are any errors, display the form again. Otherwise, insert the data
if(!count($errors)){
$sql = "UPDATE repairorder SET
date = :date,
tech = :tech,
dispatcher = :dispatcher,
booth = :booth,
worktype = :worktype,
descript = :descript,
comment = :comment,
fstop = :fstop,
devtemp = :devtemp,
counter = :counter,
numstrips = :numstrips,
fserial = :fserial,
status = :status,
odate = :odate,
cdate = :cdate,
WHERE rtransid = :rtransid";
$stmt = $db->prepare($sql);
$stmt->bindParam(':rtransid', $_POST['rtransid'], PDO::PARAM_STR);
$stmt->bindParam(':date', $_POST['date'], PDO::PARAM_STR);
$stmt->bindParam(':tech', $_POST['tech'], PDO::PARAM_STR);
$stmt->bindParam(':dispatcher', $_POST['dispatcher'], PDO::PARAM_STR);
$stmt->bindParam(':booth', $_POST['booth'], PDO::PARAM_STR);
$stmt->bindParam(':worktype', $_POST['worktype'], PDO::PARAM_INT);
$stmt->bindParam(':descript', $_POST['descript'], PDO::PARAM_STR);
$stmt->bindParam(':comment', $_POST['$comment'], PDO::PARAM_STR);
$stmt->bindParam(':fstop', $_POST['fstop'], PDO::PARAM_STR);
$stmt->bindParam(':devtemp', $_POST['devtemp'], PDO::PARAM_STR);
$stmt->bindParam(':counter', $_POST['counter'], PDO::PARAM_STR);
$stmt->bindParam(':numstrips', $_POST['numstrips'], PDO::PARAM_STR);
$stmt->bindParam(':fserial', $_POST['fserial'], PDO::PARAM_STR);
$stmt->bindParam(':status', $_POST['status'], PDO::PARAM_STR);
$stmt->bindParam(':odate', $_POST['odate'], PDO::PARAM_STR);
$stmt->bindParam(':cdate', $_POST['cdate'], PDO::PARAM_INT);
//var_dump($stmt); //used for error control in dummy server
$stmt->execute();
}
If the error message looks like this You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE rtransid = ...' at line 1, you should update your query like so.
$sql = "UPDATE repairorder SET
date = :date,
tech = :tech,
dispatcher = :dispatcher,
booth = :booth,
worktype = :worktype,
descript = :descript,
comment = :comment,
fstop = :fstop,
devtemp = :devtemp,
counter = :counter,
numstrips = :numstrips,
fserial = :fserial,
status = :status,
odate = :odate,
cdate = :cdate
WHERE rtransid = :rtransid";
You probably miss the comma after :cdate
This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 9 years ago.
Please help me, I can't using bindValue() in PDOStatement.
$statement = self::$dbConn->prepare("SELECT * FROM :tableDB WHERE id = :id");
$statement->bindValue(":id", $id, PDO::PARAM_INT);
$statement->bindValue(":tableDB", $tableDB, PDO::PARAM_STR);
$statement->execute();
$statement->setFetchMode(PDO::FETCH_ASSOC);
$result = $statement->fetchAll();
When i run this script.
$statement = self::$dbConn->prepare("SELECT * FROM :tableDB WHERE id = :id");
$statement->bindValue(":id", $id, PDO::PARAM_INT); // Return true
$statement->bindValue(":tableDB", $tableDB, PDO::PARAM_STR); // Return true
But when run to:
$statement->execute(); // Return false.
You're binding table name. You cannot do that.
Use the table name directly in the query as follows:
$statement = self::$dbConn->prepare("SELECT * FROM table_name WHERE id = :id");
$statement->bindValue(":id", $id, PDO::PARAM_INT);
// $statement->bindValue(":tableDB", $tableDB, PDO::PARAM_STR); <-- Remove this line
Update: Replaced query to use table name instead of variable.
I have two stored procedures in my database Postgres, both have the same name but the difference are the parameters.
procedure1(::string, ::integer, ::string, ::integer)
procedure1(::string, ::integer, ::integer)
In PDO doing bindParam correct, is coming STR, INT, INT but the prepere always performs procedure1.
How do I get him to understand what I call the procedure2?
Some information for more help? I clear? thanks
EDIT ===
...
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name, :domain, :geo, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('geo', $geoString, PDO::PARAM_STR);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}else{
$query = "SELECT procedure1(:name, :domain, :userid)";
$stmt = $db->prepare($query);
$stmt->bindParam('name', $name, PDO::PARAM_STR);
$stmt->bindParam('domain', $idDomain, PDO::PARAM_INT);
$stmt->bindParam('userid', $userId, PDO::PARAM_INT);
}
$result = $stmt->execute();
...
The error it gives is that he is running a procedure that requires four parameters
Try changing your $query statements to explicitly tell PDO the types, and to avoid extra code switch to bindValue (PDO uses the PARAM flags to format SQL, not to cast data types):
$bounds = null; // forced for debug
if(!is_null($bounds)){
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :geo::VARCHAR, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('geo', $geoString);
$stmt->bindValue('userid', $userId);
}else{
$query = "SELECT procedure1(:name::VARCHAR, :domain::INTEGER, :userid::INTEGER)";
$stmt = $db->prepare($query);
$stmt->bindValue('name', $name);
$stmt->bindValue('domain', $idDomain);
$stmt->bindValue('userid', $userId);
}
$result = $stmt->execute();
I have other PDO Statements that execute fine, but this one is screwed up.
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->execute( array( 0, 10 ) );
The above does NOT work, but the below does work:
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT 0,10' );
$sth->execute( array( 0, 10 ) );
So why won't the first way display any of my results when it should be giving the same response?
So here is what I have now
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, $start, PDO::PARAM_INT);
$sth->bindValue(2, $perpage, PDO::PARAM_INT);
$sth->execute();
this also does not work
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindParam(1, 0, PDO::PARAM_INT);
$sth->bindParam(2, 10, PDO::PARAM_INT);
$sth->execute();
The problem is likely that PDO will interpret any inputs as strings. You can try
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindValue(':low', 0, PDO::PARAM_INT);
$sth->bindValue(':high', 10, PDO::PARAM_INT);
$sth->execute();
Or
$low = 0;
$high = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :low,:high' );
$sth->bindParam(':low', $low, PDO::PARAM_INT);
$sth->bindParam(':high', $high, PDO::PARAM_INT);
$sth->execute();
Source: How to apply bindValue method in LIMIT clause?
Not sure if you saw this question but have you tried casting the values you send as ints?
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, (int)$start, PDO::PARAM_INT);
$sth->bindValue(2, (int)$perpage, PDO::PARAM_INT);
$sth->execute();
Or it says to do this:
$start = 0;
$perpage = 10;
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT ?,?' );
$sth->bindValue(1, intval($start), PDO::PARAM_INT);
$sth->bindValue(2, intval($perpage), PDO::PARAM_INT);
$sth->execute();
This is because "prepare" and execute with array argument thinks your datas are string by default. So they escape them with ' '. THe problem is that when you deal with limits those quotes trigger error.
The solution is bindValue
$sth = $dbh->prepare( 'SELECT * FROM `post` LIMIT :number OFFSET :start' );
$sth->bindValue("number",10, PDO::PARAM_INT);
$sth->bindValue("start",0,PDO::PARAM_INT);
$sth->execute();
What database? MySQL? SQL Server? Oracle?
In MySQL the PDO with LIMIT clause should work as in GlaciesofPacis's post. However, if you are using SQL SERVER you're not using the correct syntax. Referenced from StackOverflow question:
$query = "
DECLARE #Sort
SET ROWCOUNT :startRow
SELECT #Sort = SortColumn FROM Table ORDER BY SortColumn
SET ROWCOUNT :pageSize
SELECT ... FROM Table WHERE SortColumn >= #Sort ORDER BY SortColumn
";
$dbh->prepare($query);
$sth->bindParam(':startRow',0, PDO::PARAM_INT);
$sth->bindParam(':pageSize',10, PDO::PARAM_INT);
$sth->execute();