I'm trying to run a combination of queries from PHP. Something like this:
SELECT #rownum:=0; INSERT INTO tbl1 (`myId`, `rank`) (SELECT myId, #rownum:=#rownum+1 FROM `tbl2` WHERE 1 ORDER BY rank DESC)
Because of the user-defined var (#rownum) I have to run these queries "together". I've tried doing it either with mysqli or PDO, but both seemed to block this.
The mysqli usage I tried was:
public function multiQuery($query) {
if (#parent::multi_query($query)) {
$i = 0;
do {
$i++;
} while (#parent::next_result());
}
if (!$result) {
printf("MySQLi error:<br><b>%s</b><br>%s <br>", $this->error, $query);
}
return $result;
}
And in PDO I just expected it to work with the query() func.
How can I overcome this?
This might work better:
(set tbl1.rank to autoincrement)
TRUNCATE tbl1;
INSERT INTO tbl1 (myId) SELECT myId FROM tbl2 ORDER BY rank DESC;
It's two separate commands but you won't have to worry about the variable issue. It doesn't answer the question "how to run two different commands in one string" or "how to use variables in a query with PHP" but if you're just trying to re-rank things, that should work.
Truncate will empty tbl1 and reset the autoincrement value back to 1
Related
I'm trying to join two views which I create in a query.
The query works fine in MySQL but when I execute it with PHP it looks like it's not actually executing because I can't visualize the two views in the db.
The query I'm executing is the following:
$query1 = "CREATE OR REPLACE VIEW new_tbl AS SELECT
AnagTav.Id,
AnagTav.Riga,
AnagTav.Colonna,
AnagTav.Costo,
AnagTav.Nome,
AnagTav.NumeroPersone,
PrenPic.Data AS Occupato,
PrenPic.IdUtente
FROM `AnagraficaTavoli` AS AnagTav
LEFT JOIN PrenotazioniPicNic AS PrenPic ON PrenPic.IdTavolo = AnagTav.Id
WHERE (PrenPic.Data >= '".$dateFrom."' AND PrenPic.Data <= '".$dateTo."')
OR PrenPic.Data IS NULL
GROUP BY CASE
WHEN AnagTav.Nome != '' THEN AnagTav.Nome
ELSE AnagTav.Id
END
ORDER BY AnagTav.Riga ASC, AnagTav.Colonna;
CREATE OR REPLACE VIEW new_tbl2 AS SELECT
AnagraficaTavoli.*,
Occupato,
IdUtente
FROM AnagraficaTavoli
LEFT JOIN new_tbl ON (AnagraficaTavoli.Id = new_tbl.Id)
WHERE new_tbl.Id IS NULL;";
$result=$conn->query($query1);
After creating the 2 views I execute a second query:
if($result){
$query2 = "SELECT * FROM new_tbl
UNION
SELECT * FROM new_tbl2
ORDER BY Riga ASC, Colonna;";
$resultList=$conn->query($query2);
while($rowList=$resultList->fetch_assoc())
{
//I do stuff here
}
}
$conn is my connection to the db
I tried printing the query and executing it on MySQL, but it works fine.
I don't know why I'm getting this error and I don't know how to solve it.
This might be non obvious, but if you keep your script connected, you can access you temporary tables in separate queries. What you should do is to slice your query into three different operations, especially the "select" being a separate one. Only having single select statement in a query, php will be able to properly fetch resultset.
So I have the following MySQL query that I want to execute through a PHP script:
for($y=0;$y<$usercount;$y++){
$findweight = "replace into weight (user_id, column1)
select user_id,
0.4*column1_a+0.6*column1_bon as calc1
from history_summary where user_id=$y";
if (mysqli_query($link, $findweight)) {
echo "success <br>";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($link);
}
}
But somehow everytime I execute the script it fails to work. Everytime the script is executed, the text "success" is outputted, which means that the MySQL query should have been successfully executed, but when I check my database, nothing seems to have changed. Yet when I run the query directly such as the following:
replace into weight (user_id, column1)
select user_id,
0.4*column1_a+0.6*column1_bon as calc1
from history_summary where user_id=1
It works just fine. I'm assuming the issue is that the variable $y failed to be passed on properly to the query, but I'm not quite sure. I've tried the other solutions posted on this site but none of them seem to work. If anyone can help out that'd be great!
The DB part of me is crying because you should really be submitting one query instead of multiple queries. Specifically, if $y is a safe variable, you should have something like this:
$sql = "replace into weight (user_id, column1)
select user_id,
0.4*column1_a+0.6*column1_bon as calc1
from history_summary where user_id < $y";
There are other questions I have, such as if you really want REPLACE or you want UPDATE but that is a problem for another day.
BUT, your question was more about debugging, and it seems that the command(s) are executing successfully. Try running your query on many different values of $y. Perhaps you have encountered an edge case
The question is about debugging, so I'll respond to that, but I double-down on #mankowitz points below.
Debugging
Do you have access to the DB server? Can you watch the query log on the server to confirm that it received what you think the code is sending?
Try the old standby of println style debugging and echo out the SQL string before sending. The <pre> and --- help to make sure you are able to see any extraneous characters you might have in your SQL string:
...
echo "About to send SQL: <pre>--- $findweight ---</pre>\n"
if (mysqli_query($link, $findweight)) {
...
Is this code wrapped inside of a SQL transaction that is not (auto)committed when the script ends?
Do other, perhaps simpler queries work? Have you tried the simple SELECT 1 and echoed out the result?
More arcane and improbable given the context of the question: is fsync disabled on the server? If so, then each mysql_query does not guarantee the DB has actually written the contents to disk yet, and you may eventually see the rows get updated.
What does mysqli_query return? The code currently ignores the result other than checking if it's falsey. Store the result and introspect it.
An edge case of mysqli_query. Ten plus years ago, I encountered cases where mysql_query (note the lack of i) would not return FALSE despite a failing query. It was an oddball case of the connected user not having access to manipulate or view the rows in question, highlighting a bug in mysql_query as well as my connection string.
Database interaction
Be smart about DB queries, minimize the communication, and use bulk operations wherever possible. Your code, as structured could be rewritten in a couple of ways, both of which require only a single call to the database:
The WHERE-IN construct allows you to be very precise about which rows you address:
$ids = [];
for ( $y = 0; $y < $usercount; ++$y )
$ids[] = $y;
$ids = implode(',', $ids);
$findweight = "REPLACE INTO weight (user_id, column1)
SELECT user_id, 0.4*column1_a + 0.6*column1_bon
FROM history_summary WHERE user_id IN ($ids)";
Or, since the IDs the code addresses are contained within a contiguous range, do as #mankowitz suggested, removing the need for a for-loop entirely:
$findweight = "REPLACE INTO weight (user_id, column1)
SELECT user_id, 0.4*column1_a + 0.6*column1_bon
FROM history_summary WHERE user_id BETWEEN 0 AND $usercount";
# alternate form
$findweight = "REPLACE INTO weight (user_id, column1)
SELECT user_id, 0.4*column1_a + 0.6*column1_bon
FROM history_summary WHERE 0 <= user_id AND user_id <= $usercount";
If you absolutely must use individual per-row statements, consider a prepared statement so the DB need only parse and plan the statement once:
$findweight = 'REPLACE INTO weight (user_id, column1)
SELECT user_id, 0.4*column1_a + 0.6*column1_bon
FROM history_summary WHERE user_id = ?';
if ($psth = mysqli_prepare($link, $findweight)) {
$y = 0;
mysqli_stmt_bind_param($psth, 'i', $y);
while ( ++$y < $usercount ) {
if ( mysqli_stmt_execute( $psth ) ) {
echo "Successful REPLACE operation for user_id = $y<br>\n";
}
else {
echo "Error in REPLACE operation for user_id = $y<br>\n";
break;
}
}
}
I would like to use a query output in if statement in MySQL. Script should run a query, which counts specified rows in database table and depends on this number make decision, which another query should run which parameters.
A sample query, which gives back a number:
SELECT count(case when studentid='$studentid' AND classid='$classid' AND endsig is NULL then 1 end) as p
FROM signature
How can I handle query output p variable in PHP script or use it up in if statements?
Take a look at mysql_result() function.
You could reformat it to:
$q = mysqli_query($conn, "SELECT * FROM signature WHERE studentid='$studentid' AND classid'$classid' AND endsig is NULL");
$p = mysqli_num_rows($q);
Then you can use $p as your number, for instance
if($p == 1) {
echo "Hello World!";
}
I am new to SQL and PDO and PHP so I know I am asking a lot of myself. Still nothing ventured...
I want to combine the results of two queries and am using aliases to make the column names the same for the UNION query.
I have tried all sorts of reducing till there is nothing left to reduce, there are many more in the actual result I need for my app. I have the following code by can't think why it is not working.
Both queries work on their own but I get nothing when I combine them with a UNION. Any suggestions would be most helpful.
include ("conn/dbCon_1.php");
$sql= "(SELECT First_Name AS myResult FROM tbl_User WHERE First_Name LIKE ?)";
$sql.=" UNION ALL ";
$sql.= "(SELECT Course_Title AS myResult FROM tbl_Course WHERE Course_Title LIKE ? )";
$c1 = "%le%";
try {
$qResults = $dbConn->prepare($sql);
$qResults->execute([$c1]);
$qResults->fetch(PDO::FETCH_ASSOC);
return $qResults;
//Close connection
$dbConn = null;
} catch(PDOExcepetion $e) {
echo $e->getMessage();
}
Many thanks in anticipation and thank you for your kind attention.
Bri
As you have two placeholders - you should bind values twice:
$qResults->execute([$c1, $c1]);
You invoke the query with two parameters (like in the first Query and like in the second) even if they have the same value .. so you have to pass two parameters
$qResults->execute([$c1, $c1]);
I have one select query and one update query and I want to combine both of them.
The select query is like:
select questionDesc from myTable
where
questionId >= (
select currentQuestionid from userTable
where userId='1'
)
and questionId <= (
select currentQuestionid+4 from userTable
where userId='1'
)
For user=1, this query tries to fetch all the question Descriptions from myTable whose questionId lies between currentQuestionid and currentQuestionid+4 (currentQuestionid is a column specific to a user in the userTable). I will later use this result in my front-end.
Now, I want to update the currentQuesionid to currentQuestionid+5. This could be achieved using:
UPDATE userTable SET currentQuesionid = currentQuestionid+5 WHERE userId ='1'
I want to achieve both these queries in one database hit so as to improve the performance.
Is there any way to combine the two. I am using WAMP and the code is written in php scripts.
Any help is appreciated.
I think I have found the answer.
For combining multiple queries together we can use mysqli_multi_query() function. It is available for MySQL server versions 4.1.3 and newer. It takes multiple queries as input parameter and performs them in one db hit.
for example:
//sql queries should be separated by semi-colons
$sql = "SELECT Lastname FROM Persons ORDER BY LastName;";
$sql .= "SELECT Country FROM Customers";
// Execute multi query
if (mysqli_multi_query($con,$sql))
{
do
{
// Store first result set
if ($result=mysqli_store_result($con)) {
// Fetch row one and one
while ($row=mysqli_fetch_row($result))
{
printf("%s\n",$row[0]);
}
// Free result set
mysqli_free_result($result);
}
}
while (mysqli_next_result($con));
}
Source: http://www.w3schools.com/php/func_mysqli_multi_query.asp