As far as I can tell, I select 6 columns from the table, and I bind 6 variables so why does it tell me that it does not match?
This is for a rating script where people can vote cars.
This script works with the Insert/Select/Union but I noticed that everything was getting really slow when people voted the images from the folder structure so I would like to move the selected images to another folder where they can be accessed faster, however I seem to get a problem when trying to bind the result. This is usually not a problem for me.
Could someone explain to me why this is happening in this particular case ?
Update:
I forgot to include the category variables SORRY they are in the real script just defined up the script... So why all the downvotes? I told you the SQL works- I just tried to improve it.
$cat1 = 1;
$cat2 = 2:
$cat3 = 3;
$stmt = $dbCon->prepare(" INSERT INTO cars_daily ( cars_daily_identifier, cars_daily_source, cars_daily_views, cars_daily_votes, cars_daily_rating, cars_daily_category) "
. " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_bcar "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) "
. " UNION "
. " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_car "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) "
. " UNION "
. " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_car "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) ");
$stmt->bind_param('iii', $cat1, $cat2, $cat3);
if ($stmt->execute()) {
echo "<br><br>";
echo "Success SELECT/INSERT";
echo "<br><br>";
} else {
echo "<br><br>";
print_r($stmt->error);
echo "<br><br>";
echo "Fail SELECT/INSERT";
}
$stmt->bind_result($cars_car_id, $cars_cars_source, $cars_car_views, $cars_car_votes, $cars_car_rating, $cars_car_category);
while ($stmt->fetch()) {
copy("models/$cars_cars_source", "daily/$cars_cars_source");
}
The cause
An INSERT query won't yield records (like a SELECT would) even if the values to be inserted come from a SELECT statement.
A solution
One option is to run the INSERT query and then run a separate SELECT to fetch the values that were inserted.
$selectSQL = " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_bcar "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) "
. " UNION "
. " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_car "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) "
. " UNION "
. " (SELECT cars_car_id, cars_car_source, cars_car_views, cars_car_votes, cars_car_rating, cars_car_category "
. " FROM cars_car "
. " WHERE cars_car_category IN (?) ORDER BY RAND() LIMIT 5) ";
//run the INSERT statement
$stmt = $dbCon->prepare(" INSERT INTO cars_daily ( cars_daily_identifier, cars_daily_source, cars_daily_views, cars_daily_votes, cars_daily_rating, cars_daily_category) " . $selectSQL);
$stmt->bind_param('iii', $cat1, $cat2, $cat3);
if ($stmt->execute()) {
echo "<br><br>";
echo "Success SELECT/INSERT";
echo "<br><br>";
} else {
echo "<br><br>";
print_r($stmt->error);
echo "<br><br>";
echo "Fail SELECT/INSERT";
}
$stmt->close(); //close the prepared statement
//run the SELECT statement
$stmt = $dbCon->prepare($selectSQL);
$stmt->bind_param('iii', $cat1, $cat2, $cat3);
$stmt->execute()
$stmt->bind_result($cars_car_id, $cars_cars_source, $cars_car_views, $cars_car_votes, $cars_car_rating, $cars_car_category);
.
Related
I am trying to pass a variable that looks like this "+ interval 4" or "- interval 5" to this PDO statement.
$query = "INSERT INTO
" . $this->table_name . " (employee_id, work_date)
SELECT DISTINCT emp_num,
CURDATE() :test DAY FROM " . $this->table_name3 . "";
My bindParam
$stmt->bindParam(":test", $this->interval);
I not sure if I should be using bindValue having a hard time figuring this out.
This works fine but i know it is not right
$query = "INSERT INTO
" . $this->table_name . " (employee_id, work_date)
SELECT DISTINCT emp_num,
CURDATE() " . $this->interval . " DAY FROM " . $this->table_name3 . "";
and here is the whole function if that helps
function sqlbuild(){
$query = "INSERT INTO
" . $this->table_name . " (employee_id, work_date)
SELECT DISTINCT emp_num,
CURDATE() " . $this->interval . " DAY FROM " . $this->table_name3 . "";
$stmt = $this->conn->prepare( $query );
echo json_encode($stmt);
$stmt->bindParam(":test", $this->interval);
//$stmt->bindParam(1, $this->interval);
echo json_encode($this-> interval);
if($stmt->execute()){
return true;
}else{
return false;
}
}
How do I go about running a query on tables from a previous SHOW TABLES query? What I'm trying to do is create a PHP script that runs every 24 hours that sorts a table by "verified" descending and "votes" descending and update "nomnom" on the top result, for every table in the database.
$result = $conn->query("SHOW TABLES");
if($result->num_rows > 0) {
while($row = $result->fetch_array()) {
$sql = "SET #clan = (SELECT clan FROM " . $row[0] . " ORDER BY verified DESC, votes DESC LIMIT 1); UPDATE " . $row[0] . " SET nomnom=0 verified=0; UPDATE " . $row[0] . " SET nomnom=1 WHERE clan=#clan";
$conn->query($sql);
echo $row[0] . ' done<br>';
}
} else {
echo 'query 0';
}
This correctly echos every table name followed by done, but isn't actually updating the tables. What am I missing?
UPDATE
So I've determined that the following should work:
$sql = "SET #clan := (SELECT `clan` FROM " . $row[0] . " ORDER BY `verified` DESC, `votes` DESC LIMIT 1); UPDATE " . $row[0] . " SET `nomnom`=0, `verified`=0; UPDATE " . $row[0] . " SET `nomnom`=1 WHERE `clan`=#clan";
by echoing $sql and running the queries returned through phpmyadmin without changing anything.
Here's a line that is echoed.
SET #clan := (SELECT clan FROM aerngardh ORDER BY verified DESC, votes DESC LIMIT 1); UPDATE aerngardh SET nomnom=0, verified=0; UPDATE aerngardh SET nomnom=1 WHERE clan=#clan
It just for some reason isn't actually doing it when using
$conn->query($sql);
UPDATE 2
Figured out a way to make it work. Would mark my answer but I can't for 2 days...
Try this query
$sql = SET #clan := (SELECT clan FROM aerngardh ORDER BY verified DESC, votes DESC LIMIT 1); UPDATE aerngardh SET nomnom=0, verified=0; UPDATE aerngardh SET nomnom=1 WHERE clan=#clan
This should work
Had to split the query into 3 separate queries. Full working code:
$conn = new MySQLi($servername, $username, $password, $dbname);
$result = $conn->query("SHOW TABLES");
if($result->num_rows > 0) {
while($row = $result->fetch_array()) {
$sql = "SET #clan := (SELECT clan FROM " . $row[0] . " ORDER BY verified DESC, votes DESC LIMIT 1);";
$sql2 = "UPDATE " . $row[0] . " SET nomnom=0, verified=0;";
$sql3 = "UPDATE " . $row[0] . " SET nomnom=1 WHERE clan=#clan";
$conn->query($sql);
echo $conn->error . '<br>';
$conn->query($sql2);
echo $conn->error . '<br>';
$conn->query($sql3);
echo $conn->error . '<br>';
}
} else {
echo 'query 0';
}
If anyone would like to post how to make this a proper multi_query without getting queries out of sync errors, be my guest. I cba doing that lol.
I have a mysqli SELECT query that is using an Inner Join and I noticed a big problem: it doesn't select rows where the column value for the condition is null (because NULL doesn't exist in the second table). Here's my code:
<?php
$sql = mysqli_connect(/* CONNECTION */);
$query = "SELECT " .
"e.EQUIPMENT_ID, " .
"e.CUSTOMER_ID, " .
"e.DESCRIPTION, " .
"e.LOCATION, " .
"e.JOB_SITE, " .
"e.PROJECT_NAME, " .
"jb.DESCRIPTION AS JOB_SITE_NAME " .
"FROM equipments e " .
"INNER JOIN jobsites jb ON jb.JOBSITE_ID = e.JOB_SITE " .
"WHERE e.CUSTOMER_ID = 1 ".
"ORDER BY e.EQUIPMENT_ID ASC";
$results = mysqli_query($sql, $query);
if(!isset($data)) $data = array(); $cc = 0;
while($info = mysqli_fetch_array($results, MYSQLI_ASSOC)){
if(!isset($data[$cc])) $data[$cc] = array();
///// FROM TABLE equipments /////
$data[$cc]['EQUIPMENT_ID'] = $info['EQUIPMENT_ID'];
$data[$cc]['DESCRIPTION'] = $info['DESCRIPTION'];
$data[$cc]['LOCATION'] = $info['LOCATION'];
$data[$cc]['PROJECT_NAME'] = $info['PROJECT_NAME'];
$data[$cc]['JOB_SITE_ID'] = $info['JOB_SITE'];
///// FROM TABLE jobsites /////
$data[$cc]['JOB_SITE'] = $info['JOB_SITE_NAME'];
$cc++;
}
print_r($data);
?>
So, as I said, the code returns values but only if the column "JOB_SITE" inside "equipments" has a jobsite id (not null). The ugly solution is to create a row inside the table "jobsites" with a jobsite_id named "empty", but if I can skip this, I will.
Is there a way to join only if e.JOB_SITE is not null ?
You can use LEFT JOIN in SQL query.
$query = "SELECT " .
"e.EQUIPMENT_ID, " .
"e.CUSTOMER_ID, " .
"e.DESCRIPTION, " .
"e.LOCATION, " .
"e.JOB_SITE, " .
"e.PROJECT_NAME, " .
"jb.DESCRIPTION AS JOB_SITE_NAME " .
"FROM equipments e " .
"LEFT JOIN jobsites jb ON jb.JOBSITE_ID = e.JOB_SITE " .
"WHERE e.CUSTOMER_ID = 1 ".
"ORDER BY e.EQUIPMENT_ID ASC";
This query will return NULL VALUE for column JOB_SITE_NAME if there is no row matching jb.JOBSITE_ID in equipments table
I have a working script that selects image fields in all tables and empty their values if the physical file doesnt exist.
$query1 = "SELECT table_name,column_name
FROM information_schema.columns
WHERE table_schema='schemaname' AND column_name like '%image%' or column_name='video'";
$result1 = mysql_query($query1) or die(mysql_error() . " -- " . $query1);
while($row1 = mysql_fetch_row($result1)){
if (!strpos($row1[0],'backup') > 0){
$sql = "Select COLUMN_NAME FROM information_schema.columns WHERE TABLE_NAME = '".$row1[0]."' AND EXTRA = 'auto_increment'";
$resultcol = mysql_query($sql);
$rowcol = mysql_fetch_row($resultcol);
$query2 = "SELECT " . $row1[1] . ", " .$rowcol[0] . "
FROM " . $row1[0] . "
WHERE " . $row1[1] . " != '' AND " . $row1[1] . " IS NOT NULL
";
echo $query2 . "<br>";
$result2 = mysql_query($query2) or die(mysql_error() . " -- " . $query2);
while ($rowdb = mysql_fetch_row($result2)){
if (!strpos($rowdb[0],'facebook') > 0 && !file_exists($img_root.'/'.$rowdb[0])){
$sql = "UPDATE ".$row1[0]." SET ". $row1[1] . " = '' WHERE " . $rowcol[0]. "= ".$rowdb[1];
echo $sql . "<br><br>";
$delete_count++;
//mysql_query("UPDATE ".$row1[0]." SET ". $row1[1] . " = '' WHERE id = ".$row1["id"]);
}
}
}
}
The script is working fine, but it takes time though, I was wondering if there is a smarter way (more optimized) to get the same function ? Thanks
You have several options.
The first, and IMHO the best option - is to use an ORM -
I recommend Idiorm, Doctrine, or Propel.
Then, you would use something like (in idiorm) fetch_all and loop through that, instead of through the mysql_fetch_row()
Second, you should switch to mysqli -- the functions you are using are deprecated in PHP5.5
Third -- you could just use either mysql_fetch_array or mysql_fetch_all (I'm not sure, but I would be on the latter)
The key thing here is:
Do not loop mysql functions.
Performance wise the problem is that you are looping through a result set, and performing queries for each row.
However with your output it is difficult to eliminate this. Otherwise you might be able to do the whole script in a single SQL statement.
Minimal clean up to just remove one of the selects:-
<?php
$query1 = "SELECT a.table_name, a.column_name, b.COLUMN_NAME AS auto_inc_col
FROM information_schema.columns a
INNER JOIN information_schema.columns b
ON a.table_name = b.table_name AND b.EXTRA = 'auto_increment'
WHERE table_schema='schemaname' AND column_name like '%image%' or column_name='video'";
$result1 = mysql_query($query1) or die(mysql_error() . " -- " . $query1);
while($row1 = mysql_fetch_assoc($result1))
{
if (!strpos($row1['table_name'],'backup') > 0)
{
$query2 = "SELECT " . $row1['column_name'] . ", " .$row1['auto_inc_col'] . "
FROM " . $row1['table_name'] . "
WHERE " . $row1['column_name'] . " != '' AND " . $row1['column_name'] . " IS NOT NULL
";
echo $query2 . "<br>";
$result2 = mysql_query($query2) or die(mysql_error() . " -- " . $query2);
while ($rowdb = mysql_fetch_row($result2))
{
if (!strpos($rowdb[0],'facebook') > 0 && !file_exists($img_root.'/'.$rowdb[0]))
{
$sql = "UPDATE ".$row1['table_name']." SET ". $row1['column_name'] . " = '' WHERE " . $row1['auto_inc_col']. "= ".$rowdb[1];
echo $sql . "<br><br>";
$delete_count++;
//mysql_query("UPDATE ".$row1['table_name']." SET ". $row1['column_name'] . " = '' WHERE id = ".$row1["id"]);
}
}
}
}
?>
When I tested this query out in mysql it was fine but when I went to run it in php I keep getting this error.
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 'SELECT *, (#rownum := #rownum + 1) AS rank FROM ( SELECT *, (totalWins+(total' at line 1
This is the php code I have.
<?php
$sql = " SET #rownum = 0; ";
$sql .= " SELECT *, (#rownum := #rownum + 1) AS rank FROM ( ";
$sql .= " SELECT *, (totalWins+(totalPushs*.5)) AS totalPoints, totalWins+totalLost+totalPushs AS totalBets FROM ( ";
$sql .= " SELECT *, SUM(win) AS totalWins, SUM(lost) AS totalLost, SUM(push) AS totalPushs FROM ( ";
$sql .= " SELECT *, (finalResult = 'Winner') AS win, (finalResult = 'Loser') AS lost, (finalResult = 'Push') AS push FROM ( ";
$sql .= " SELECT " . $db_prefix . "users.userID, userName, ";
$sql .= " IF (pickID=visitorID, visitorResult, homeResult) AS finalResult ";
$sql .= " FROM " . $db_prefix . "users ";
$sql .= " JOIN " . $db_prefix . "picks ";
$sql .= " ON " . $db_prefix . "users.userID = " . $db_prefix . "picks.userID ";
$sql .= " JOIN " . $db_prefix . "schedule ";
$sql .= " ON " . $db_prefix . "picks.gameID = " . $db_prefix . "schedule.gameID ";
$sql .= " ) x ";
$sql .= " ) x ";
$sql .= " GROUP BY userID ";
$sql .= " ) x ";
$sql .= " ) x ";
$sql .= " ORDER BY totalPoints DESC, totalWins DESC, totalPushs DESC, totalLost ";
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
echo $row[rank] . '|' . $row[userName]. '|' . $row[totalWins] . '|' . $row[totalLost] . '|' . $row[totalPushs] . '|' . $row[totalPoints];
echo '<br>';
}
?>
I can get the php code to work without the first line of code
$sql = " SET #rownum = 0; ";
but it won't echo out the rank column.
Is there something I have to do differently to line one of the code when it's in php?
mysql_query does not support running more than one query at a time. You must first run
mysql_query("SET #rownum = 0;");, then you can run the rest of your query in a second mysql_query call.
Please try tablename.* instead of *