I'm trying to execute multiple queries, but something is wrong.
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
$sql = "
UPDATE tmatria SET par = " . $newpar . ", inde = " . $newinde . " WHERE id =" . $cutid . ";
SELECT * FROM tmatria ORDER BY inde ASC;
SET #i := 0;
UPDATE tmatria SET inde = #i := #i + 1;
";
try {
$db->exec($sql);
}
catch (PDOException $e) {
echo $e->getMessage();
die();
}
I want update some columns, then sort table by inde column and finally set inde values to 1 2 3...
I think lines UPDATE tmatria SET par... and SELECT * FROM tmatria ORDER BY inde ASC; are critical, but cannot see what's wrong.
Any help?
You have some fundamental misunderstanding about how to use SQL. You do a SELECT ... ORDER BY, and then you expect the following UPDATE to obey the same ordering. The UPDATE is ordering the table in its natural order, it doesn't pay attention to the SELECT query at all.
And as a matter of coding, there's no need or benefit to executing multiple SQL statements in one call. PDO permits it, but it's not a good habit. You should execute one SQL statement per call. As long as you use the same db connection, the session variable #i will retain its value.
Also use prepared queries when you want to combine PHP variables with a SQL statement; don't concatenate PHP variables into your SQL string.
try {
$sql = "UPDATE tmatria SET par = ?, inde = ? WHERE id = ?";
$stmt = $db->prepare($sql);
$stmt->execute([$newpar, $newinde, $cutid]);
$sql = "SET #i := 0";
$db->exec($sql);
$sql = "UPDATE tmatria SET inde = #i := #i + 1 ORDER BY inde ASC";
$db->exec($sql);
}
catch (PDOException $e) {
echo $e->getMessage();
die();
}
It also looks like you're trying to renumber inde after every update, to force that column to have consecutive values. This will get slower and slower the more rows you have in the table, right?
You should reconsider why you need that column to have consecutive values.
You need to pass your queries to PDO one at a time. You can still use variables like #i, because PDO will run your queries in order. But it won't run a mess of queries in one call.
Related
i'm trying to create a multiple photo uploading script in php. All seems to be working fine except the update query. tried updating it manually in phpmyadmin and the problem of not updating persists don't know what to do can any experts help me solve this problem.
here is the update query:
try {
$sql1="update photos
set
filename='{$db_file_name}',
upload_date=now() where user='{$_SESSION['id']}' ";
$st1=$conn->prepare($sql1);
$st1->execute();
}
catch (Exception $exc) {
echo $exc->getMessage();
}
First of all, I would verify again whether all the variables you are using are correct (photos, filename, etc.). i.e. compare them letter by letter with your table. If that looks alright, a little more information wouldn't be bad. Are you getting any errors? If so, what are they saying? What else have you tried so far?
Moreover, I would suggest making your code a little easier to read like so:
/* create a prepared statement */
if ($st1 = $conn->prepare("UPDATE `photos` SET `filename` = ?, `upload_date` = ? WHERE `user` = ?")) {
/* bind parameters (ssi = string, string, integer)*/
$st1->bind_param("ssi", $db_file_name, now(), $_SESSION['id']);
/* execute query */
$st1->execute();
/* close statement */
$st1->close();
}
user is a keyword, better use backticks around it. See: https://dev.mysql.com/doc/refman/8.0/en/keywords.html
try {
$sql = "UPDATE `photos`
SET `filename` = :filename,
`upload_date` = NOW()
WHERE `user` = :sess_id";
$stmt = $conn->prepare($sql);
$stmt->bindValue(":sess_id", $_SESSION['id']);
$stmt->bindValue(":filename", $db_file_name);
$stmt->execute();
} catch (....) {
....
}
Perhaps better still, don't use keywords as column names, try userId.
I have a little bit of a problem figuring out where the error comes from.
The background is that I have a table and using a form I update the values into the table and can update them and delete them using different buttons.
This leaves the auto incremented IDs in disorder after deletion and I thought it would be just good practice to see if I could reset the order using a simple button.
Otherwise I've been updating them using
SET #num := 0;
UPDATE tableName SET id = #num := (#num+1);
ALTER TABLE tableName AUTO_INCREMENT = 1;
in phpmyadmin. I got it from this answer :
Auto Increment after delete in MySQL
//resort database
if(isset($_POST['resort'])){
// Database connection opening
$mysqli = NEW MySQLi('localhost','root','','powerstations'); //our server, the username, the password (empty), the database itself
if($mysqli) {
echo "Connected!";
} else {
echo "Problem.";
}
$sql_resort = "SET #num := 0; ";
$sql_resort .= "UPDATE powerdata SET id = #num := (#num+1); ";
$sql_resort .= "ALTER TABLE powerdata AUTO_INCREMENT = 1; ";
if ($mysqli->query($sql_resort) === TRUE) {
echo "Resorted successfully";
} else {
echo "Error: " . $sql_resort . "<br>" . $mysqli->error;
}
$mysqli->close();
The error I get is:
SET #num := 0; UPDATE powerdata SET id = #num := (#num+1); ALTER TABLE powerdata AUTO_INCREMENT = 1;
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 'UPDATE powerdata SET id = #num := (#num+1); ALTER TABLE powerdata AUTO_INCREMENT' at line 1
I tried to search for typos by putting the multi line statement into phpmyadmin, but found nothing and I don't see where the problem with the "code structure" is if there is one.
When attempting do execute multiple statements in a single query you have to call $mysqli->multi_query($sql) not $mysqli->query($sql).
So you will need to update
if ($mysqli->query($sql_resort) === TRUE) {}
to
if ($mysqli->multi_query($sql_resort) === TRUE) {
I'm trying to create a third table taking two indexes from two different tables for creating a correlation between them using following code:
$query1 = "select iduniverse from universe";
$query2 = "select idfiles from files";
$query3 = "select iduniFiles from uniFiles where filesId = ? and universeId = ?";
$query4 = "insert into uniFiles (filesId, universeId) values (?,?)";
if($stmt1 = $conn->prepare($query1)){
if($stmt2 = $conn->prepare($query2)){
if($stmt3 = $conn->prepare($query3)){
if($stmt4 = $conn->prepare($query4)){
$stmt1->execute();
$stmt1->bind_result($iduniverse);
while($stmt1->fetch()){
$stmt2->execute();
$stmt2->bind_result($idfiles);
while($stmt2->fetch()){
$stmt3->bind_param("ii", $idfiles, $iduniverse);
$stmt3->execute();
$stmt3->store_result();
if($stmt3->num_rows == 0){
$stmt4->bind_param("ii", $idfiles, $iduniverse);
$stmt4->execute();
}
}
}
}
$stmt4->free_result();
}
$stmt3->free_result();
}
$stmt2->free_result();
}
$stmt1->free_result();
But if I put an echo "here\n" after second while loop:
while($stmt2->fetch()){
echo "here\n";
...
When I launch my code I don't see anything on screen output and also table uniFiles remains empty.
I have already checked query via SQL Browser and works without any issue. So I don't understand where is the mistake.
What is wrong in my script?
You can create a join table using INSERT INTO INTO SELECT ...
insert into uniFiles (filesId, universeId)
select iu.iduniverse, if.idfiles
from universe iu
join files if on if.idfiles = iu.idfiles
If there could be duplicates, then combine with INSERT IGNORE
insert ignore into uniFiles (filesId, universeId)
select iu.iduniverse, if.idfiles
from universe iu
join files if on if.idfiles = iu.idfiles
A mysqli connection can only hold a single active prepared statement at a time.
Therefore, you can't have nested prepared statements active on the same connection. You'll have to have a separate connection for each level of the nesting if you need to keep them all active (at least for each one you don't want squashed by the next level's query.
For example: I have a table name tbl_admin and I have so many table elements within that table.
Like (id, fname, lname, contact_info, email, ip, date, status, etc.and so on upto 20 elements).
Now I need to exclude only 3 elements from that table as you can say (fname, lname and contact_info) and select all others. Is this possible by using the mysql query?
Please help me if this is possible. Thanks,
Short Answer
You can't exclude columns explicitly, but you can do so implicitly by selecting only the other columns:
SELECT
ID,
EMAIL,
IP,
DATE,
STATUS
FROM tbl_admin
Long Answer
It turns out I was wrong with the short answer, technically there is a way as illustrated with the question here.
To do this in PHP, I'd recommend creating a view in the MySQL database that would encapsulate the SQL. Then you would just select * from that view.
Alternatively, you could create a stored procedure, and pass in the names of the columns that you want to be filtered out.
Try:
$result = mysql_query("SHOW COLUMNS FROM tbl_admin");
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$columns[] = $row['Field'];
}
}
//fill all columns here that you want to exclude
$columns_to_exclude = array('fname','lname','contact_info');
$sql = "SELECT (";
foreach($columns as $ind=>$val){
if(!in_array($val,$columns_to_exclude))
{
$sql .= $val.", ";
}
}
$sql = rtrim($sql,", ");
$sql .= ") FROM tbl_admin;";
echo $sql;
Select fname,sname,contact from table_admin
Yes, so you will have something like this:
SELECT
id,
fname,
lanem
FROM
tbl_admin
You just need to specify what are those and in what order. Instead of using the * to fetch all records (columns) in its default order.
Edit
SET #sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_omit>,', '') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
Actually, I just got it from another's posts so all credits goes to him. HERE
Latest Answer
ANSWER BY Mahomedalid in Select all columns except one in MySQL?
SET #sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_omit>,', '') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
For your situation replace the <columns_to_omit> with fname,lname,contact_info
Old Answer
Syntax for retrieving particular column values from table is
SELECT column_name(s)
FROM table_name
All columns can be retrieved using SELECT * instead of SELECT column_name(s)
if you are directing your question towards a particular language like PHP then the syntax can be like this
<?php
$con=mysqli_connect("localhost","username","password","database");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT fname,lname,contact_info FROM tbl_admin");?>
I want to set a variable to use in a mysqli query. This doesn't quite work. Prior to mysqli I used to set query calls. I played around with db->multi_query($sql) with no luck. Anyone out there have an idea how to make this work including a set statement?
$sql = 'SET #rownum := 0;';
$sql .= 'SELECT #rownum :=#rownum + 1 AS Rank, User_Id, COUNT(User_ID) AS Block_Count
FROM Block_Owners;
$stmt = $db->prepare($sql);
$stmt->bind_param('ii', $world, $userId);
// execute the query
$stmt->execute();
Do it in two separate queries:
$db->query('SET #rownum := 0');
$sql = 'SELECT #rownum :=#rownum + 1 AS Rank, User_Id, COUNT(User_ID) AS Block_Count FROM Block_Owners'
$stmt = $db->prepare($sql);
$stmt->bind_param('ii', $world, $userId);
$stmt->execute();
Note, however, that the query you want to run will always return a single row (with Rank = 1) since you are using an aggregate function without GROUP BY.