I have a query in PDO which contains multiple actions. I first looked at this question to know wether or not multiple queries are even possible.
My code looks like this:
$stmt = $db->prepare(
"UPDATE
tbl_user_dashboards
SET
is_active = 0
WHERE
id_user_key_fk = 1;
INSERT INTO
tbl_user_dashboards(id_user_key_fk, dashboard_name, dashboard_description, is_active)
VALUES
(1, 'bla', 'blabla', 1);
SELECT
id_dashboard AS did,
dashboard_name AS dname,
dashboard_description AS ddesc,
is_active
FROM
tbl_user_dashboards
WHERE
id_user_key_fk = 1
ORDER BY
id_dashboard ASC;"
);
$stmt->execute();
$data = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$data[] = $row;
}
My problem is, is that the UPDATE and INSERT work fine, but the SELECT doesn't work (my JSON object stays empty and I don't get any errors, just [] as my output).
When I isolate the UPDATE and the INSERT and run the SELECT as a seperate statement after the UPDATE and INSERT, then it does work but that's not my preferable solution.
Any thoughts on this?
Related
I am trying to loop through an array ($lineup_selected) that corresponds to a player row in a database. For each player I would like to execute an UPDATE query to the database that adds the value of $submissions_selected to the total_picks column. I am struggling with the code as it fails to execute the query. Any help please?!
// Select team & formation
$team_selected = "team1";
$lineup_selected = array("player1", "player2", "player3");
$submissions_selected = 4000;
// Loop through and update total_picks for each player in database present in lineup_selected array
$player_picks_query = "SELECT full_name, total_picks FROM table WHERE team=$team_selected";
$result = mysqli_query($conn, $player_picks_query);
while($row = mysqli_fetch_assoc($result)) {
$player = mysql_real_escape_string($row["full_name"]);
$add_player_picks = "UPDATE table
SET total_picks = total_picks + $submissions_selected
WHERE full_name = '$player'";
}
why not:
UPDATE table
SET total_picks = total_picks + $submissions_selected
WHERE team = '$team_selected'
this way you have only one query to execute and let your database do the looping. Else you would first select some records and then have your database update each one of them to update the record.
I assume the fullname is unique. If not, it would mean your version can have the update-query modify multiple records each time and so my approach is invalid
-- and I seem to repeat a lot of the comments when stating to sanitize and escape your input to be save(r).
edit:
combined it should come to:
// set team & formation
$team_selected = "team1";
$lineup_selected = array("player1", "player2", "player3");
$submissions_selected = 4000;
$updatequery = "UPDATE table
SET total_picks = total_picks + ?
WHERE team= ?";
$stmt = mysqli_prepare($updatequery);
mysqli_stmt_bind_param($stmt, "is", $submissions_selected, $team_selected);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
Myself I am more into the pdo approach, but syntax should be like this.
In your select request you have a team that is obviously a String. So, maybe you can try your request like : "SELECT full_name, total_picks FROM table WHERE team='$team_selected'"
I don't know if PHP is smart enough to put the quotes.
I think it will be better if you use only an update statement.
First of all you implode your array
$lineup_selected = array("player1", "player2", "player3");
$players='".implode("','",$lineup_selected )."';
Now you can update the table
$updateStmt="UPDATE table
SET total_picks = total_picks + $submissions_selected
WHERE full_name in (".$players.") and team=".$team_selected.";
There are many questions on SO about this but I cannot find one that quite meets my situation.
I want to use the values in some fields/columns of a table to set the value of a third field/column
In other words something like:
table races
athleteid|difficulty|score|adjustedscore
$sqlSelect = "SELECT athleteid,difficulty,score FROM races";
$res = mysql_query($sqlSelect) or die(mysql_error());
while ($row = mysql_fetch_array($res)){
$adjustedscore=difficulty*score;
$sqlupdate = "UPDATE race, set adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
$resupdate = mysql_query($sqlupdate);
}
My understanding, however, is that MYSQL does not support update queries nested in select ones.
Note, I have simplified this slightly. I am actually calculating the score based on a lot of other variables as well--and may join some tables to get other inputs--but this is the basic principal.
Thanks for any suggestions
You can run:
UPDATE `races`
SET `adjustedscore` = `difficulty` * `score`
WHERE `athleteid` IN (1, 2, 3, ...)
First of all, as previous commentators said, you should use PDO instead of mysql_* queries.
Read about PDO here.
When you'll get data from DB with your SELECT query, you'll get array. I recommend you to use fetchAll() from PDO documentation.
So, your goal is to save this data in some variable. Like you did with $row.
After that you'll need to loop over each array and get your data:
foreach($row as $r) {
//We do this to access each of ours athlete data
$adjustedscore= $row[$r]["difficulty"]* $row[$r]["score"];
//Next row is not clear for me...
$query = "UPDATE race SET adjustedscore = '$adjustedscore' WHERE athletes = 'athletes'";
And to update we use PDO update prepared statement
$stmt = $dbh->prepare($query);
$stmt->execute();
}
I have this PHP Code:
$stmt = $pdo_conn->prepare("DELETE from tickets_extra_emails where ticketnumber = :ticketnumber ");
$stmt->execute(array(':ticketnumber' => $ticket["ticketnumber"]));
$cc_contact_line = '';
foreach(explode("\n", $_POST["cc_contacts"]) as $cc_contact_line) {
//then insert new if its not blank
if(filter_var($cc_contact_line, FILTER_VALIDATE_EMAIL)) {
//see if it currently exists
$stmt = $pdo_conn->prepare("SELECT * from tickets_extra_emails where ticketnumber = :ticketnumber and email_address = :email_address ");
$stmt->execute(array(':ticketnumber' => $ticket["ticketnumber"], ':email_address' => $cc_contact_line));
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
if(count($records) == 0) {
echo 'insert '.$ticket["ticketnumber"].' - '.$cc_contact_line.'<br>';
$stmt = $pdo_conn->prepare("INSERT into tickets_extra_emails (ticketnumber, email_address) values (:ticketnumber, :email_address) ");
$stmt->execute(array(':ticketnumber' => $ticket["ticketnumber"], ':email_address' => $cc_contact_line));
}
}
}
that makes each line of a textarea a variable in a foreach loop.
if i put lines in the textarea and submit the form, it saves the data but then if there is already data in and i submit the form, it removes it.
what do i have wrong in my code? I have commented everything it does
Theres a significant difference between MySQL INSERT and UPDATE.
You will need to check against the database where you are inserting to and use a query to check if there is data existing in that row. Based on that query you can restructure your insert statement to be conditional and switch from an INSERT to an UPDATE.
Deleting existing data will not allow you to re-insert into the rows, the rows are existing and therefor require UPDATE. However if you are removing whole rows then you can indeed re insert the rows. I see this as not entirely efficient, when you can utilize the efficiency of UPDATE to its benefit here.
AFAIK, fetchAll will fail if there are 0 rows, so you won't be able to run a count on the records. Do you have errors enabled or logged?
I see what you are trying to do and why you want to delete then reinsert, although maybe not the best approach.
Update: Apparently rowCount() shouldn't be relied on for selects, so I think the best alternative is to change your select query to select a count. This will always return a value as long as the query is valid so you shouldn't have to worry about the fetch failing. As you noticed below, I just changed the SELECT * to a SELECT count(*) so this will count how many rows match your constraints. Then use fetchColumn() to select the first column of the first row (the count).
$stmt = $pdo_conn->prepare("SELECT count(*) from tickets_extra_emails where ticketnumber = :ticketnumber and email_address = :email_address ");
$stmt->execute(array(':ticketnumber' => $ticket["ticketnumber"], ':email_address' => $cc_contact_line));
$records = $stmt->fetchColumn();
I am trying to run an update on a MySQL table that will swap the contents of 1 field with the contents of another (both in the same table).
Here is the basic structure of the table:
id SKU related
== === =======
1234 SKU001 1234,8889,2209
5544 SKU855 2209,1234
2209 SKUYYT 5544
What I need to do is swap the related field for the relavent SKU (so that it lists the sku's instead of the id's). So it would end up looking like this:
id SKU related
== === =======
1234 SKU001 SKU001,SKU111,SKUYYT
5544 SKU855 SKUYYT,SKU001
2209 SKUYYT SKU855
So what I'm trying to achieve is the id in the related field would have been replaced with the SKU that relates to that id.
What I'm currently doing is this:
SELECT id, sku FROM my_table
Then looping through all id's with PHP and updating the table like so:
UPDATE my_table SET related = REPLACE(related, '5544', 'SKU855');
This seems to work but I have 9000+ rows and multiple id's in the related column and it's taking hours to complete
Can anyone suggest a better way of achieving this? (Ideally in MySQL)
Many thanks
If you have access to PHP with this update, I would suggest you do the following:
$rows = some_method_to_load_all_rows_from_your_table();
$id_to_sku = array();
// Loop through all rows to cache their SKU numbers and directly associate them to their row's PK.
foreach ($rows as $row) {
$id_to_sku[$row['id']] = $row['SKU'];
}
// Loop through all rows a second time to then break apart, find, and replace the related IDs.
foreach ($rows as $index => $row) {
$related_ids = explode(',', $row['related']);
foreach($related_ids as &$related_id) {
if (isset($id_to_sku[$related_id]]) {
$related_id = $id_to_sku[$related_id]];
} // else the ID couldn't be found.
}
$rows[$index]['related'] = implode(',', $related_ids);
}
// $rows now contains the related string with the SKU numbers instead of ID numbers.
method_to_update_all_rows_with_new_related_value($rows);
Essentially, doing this in raw SQL is going to be very difficult, and you will be left with a very complex query. The best way is to abstract the detecting and replacing of the IDs / SKU numbers into PHP, where this becomes a much easier and more readable platform to work on.
The code loads all rows in the table, then loops through each row to cache it’s ID and SKU number separately.
Then, we loop through each row again, break apart the related field into an array of IDs, replace those IDs with their correct SKU code using the cache we created, and insert them back into $rows.
$rows becomes the new updated table set. From there, it’s a case of creating a giant UPDATE statement, or looping through each row and executing a single UPDATE statement for each one. Looping in PHP and issuing an UPDATE for each row would be slower as making a query has overhead. But you can also implement the loop in SQL, using stored procedure, avoiding the overhead on communication between your application and database.
/*
create my_table_temp with same structure as in my_table
*/
$mapping = array();
$sth = $dbh->prepare("SELECT id, SKU FROM my_table");
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row) {
$mapping[$row['id']] = $row['SKU'];
}
$sql = 'insert into my_table_temp(id, SKU, related) VALUES ';
$params = array();
$sth = $dbh->prepare("SELECT * FROM my_table");
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row) {
$related = explode(',', $row['related']);
foreach($related as &$val) {
$val = $mapping[$val];
}
$sql .= '(?, ?, ?),';
$params[] = $row['id'];
$params[] = $row['SKU'];
$params[] = implode(',', $related);
}
$sql = rtrim($sql, ',');
$sth = $dbh->prepare($sql);
$sth->execute($params);
/*
update my_table
set related = q.related
from (
select sku, related
from my_table_temp
) q
where my_table.sku = q.sku;
drop table my_table_temp;
*/
When You are asking to do it in mysql , then it would be possible by using CURSOR and dynamic query.
DELIMITER //
CREATE PROCEDURE `all_update`()
BEGIN
DECLARE ids INT;
DECLARE sname VARCHAR(255);
DECLARE finished INTEGER DEFAULT 0;
DECLARE cursor1 CURSOR FOR SELECT id,SKU FROM testing;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN cursor1;
update_table: LOOP
FETCH cursor1 INTO ids,sname;
IF finished = 1 THEN
LEAVE update_table;
END IF;
SET #s = CONCAT('UPDATE testing SET related = REPLACE(related,', ids,', "',sname,'")');
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END LOOP update_table;
CLOSE cursor1;
END//
Fiddle is http://sqlfiddle.com/#!2/298a7/1
I'm trying to update multiple rows in one table in MySQL database by doing this. And its not working.
$query = "UPDATE cart SET cart_qty='300' WHERE cart_id = '21';
UPDATE cart SET cart_qty='200' WHERE cart_id = '23';
UPDATE cart SET cart_qty='100' WHERE cart_id = '24';";
mysql_query($query,$link);// $link is specified above
Anyone know what is wrong with this.
From the PHP documentation:
mysql_query() sends a unique query (multiple queries are not supported)
The ; separates SQL statements, so you need to separate the queries if you want to continue using the mysql_query function...
mysql_query can't use multiple queries.
The easiest thing is to just run them separately. I believe you can do multi query but I haven't tried it.
$updateArray = array(21=>300,23=>200,24=>100);
foreach($updateArray as $id=>$value)
{
$query = "UPDATE cart SET cart_qty='$value' WHERE cart_id = '$id'";
mysql_query($query,$link);// $link is specified above
}
This will accept a combination of IDs and their corresponding cart value. Looping though, it builds the query and executes it. The array can then come from a variety of sources (results from another query, form inputs or, as in this case, hard-coded values)
Update:
If you really need to execute all in one, heres the PHP info on multi query:
mysqli::multi_query
You can do it this way:
UPDATE table
SET col1 = CASE id
WHEN id1 THEN id1_v1,
WHEN id2 THEN id2_v1
END
col2 = CASE id
WHEN id1 THEN id1_v2,
WHEN id2 THEN id2_v2
END
WHERE id IN (id1, id2)
This example shows updating two different columns in two different rows so you can expand this to more rows and columns by cludging together a query like this. There might be some scaling issues that makes the case statement unsuitable for a very large number of rows.
You'll need to send them as separate queries. Why not add the queries as strings to an array, then iterate through that array sending each query separtely?
Also check this thread for another idea
This isn't the best method.. But if you need to do multiple queries you could use something like...
function multiQuery($sql)
{
$query_arr = explode(';', $sql);
foreach ($query_arr as $query)
{
mysql_query($query);
}
}
another example of a helper query
function build_sql_update($table, $data, $where)
{
$sql = '';
foreach($data as $field => $item)
{
$sql .= "`$table`.`$field` = '".mysql_real_escape_string($item)."',";
}
// remove trailing ,
$sql = rtrim($sql, ',');
return 'UPDATE `' . $table .'` SET '.$sql . ' WHERE ' .$where;
}
echo build_sql_update('cart', array('cart_qty' => 1), 'cart_id=21');