SELECT + INSERT in the same query - php

This is what I'm using now
public function nuevaPlantilla(){
$query = $this->sql->prepare("SELECT max(did) as nuevodid FROM ".self::tabla_plantillas);
$exc = $query->execute();
if (!$exc){
return false;
}
$resultado = $query->get_result();
$datos = $resultado->fetch_all();
$did = ($datos[0][0]*1)+1;
$query = $this->sql->prepare("INSERT INTO ".self::tabla_plantillas." (did, quien, tipo_usuario, did_filtro, valor, pagina) VALUES (?,?,?,?,?,?)");
if (!$query){
return false;
}
$query->bind_param("isssss", $did, $this->quien, $this->tipo, "", "", $this->qh);
$exc = $query->execute();
$query->close();
return $exc;
}
It works, but, is it possible to make the same thing with only one query?
PLEASE DO NOT SUGGEST ME TO USE AUTO_INCREMENT ID. Because more than one row would have the same did.

Use something like this:
insert into destination_table (id, col2, col3)
select * from
(
select coalesce(max(id),0)+1,
'other_value',
3
from source_table
) x
SQLFiddle demo

INSERT INTO table (field, field)
SELECT field, field FROM table
WHERE field='something';

Related

Archive some entities with inheritance

I have a hard problem to solve and I don't know how to do it.
I want to archive some entities and then delete them from initial tables. Problem is these entities are linked together. I have a code which is close to working but I think it's not a clean way to do it. It's composed of SQL queries which copy rows with their IDs to new tables.
Another problem is that I don't need some fields to archive so archive entities are not exactly the same as initial entities.
I'm using raw SQL query and not DQL because of the size of my tables.
I want to archive these entities : Colle, ColleQC, QC, PasserColle, Reponse, ReponseQC, StatistiqueColle, StatistiqueQuestion, RepartitionColle, RepartitionQuestion, Tuteur
TO
BanqueColle, BanqueColleQC, BanqueQC, BanquePasserColle, BanqueReponse, BanqueReponseQC, BanqueStatistiqueColle, BanqueStatistiqueQuestion, BanqueRepartitionColle, BanqueRepartitionQuestion, AncienAdherent.
I'll use these archive for another part of my app.
Sample of table structure :
(Tuteur and AncienAdherent extend User)
Here's a part of the code I made to archive but I don't think it's a clean way to do it :
public function archiveTuteurs() {
$db = $this->em->getConnection();
$query = "INSERT INTO ancien_adherent (id)
SELECT u.id
FROM user u
WHERE discr = 'tuteur'";
$stmt = $db->prepare($query);
$stmt->execute();
$query2 = "UPDATE user
SET user.discr = 'ancien'
WHERE discr = 'tuteur'";
$stmt = $db->prepare($query2);
$stmt->execute();
return true;
}
public function archiveColles() {
$db = $this->em->getConnection();
$query = "INSERT INTO banque_colle (id, typeColle, nom, temps_epreuve, matiere_id, dateCreation, ordre, discr)
SELECT colle.id, colle.typeColle, colle.nom, colle.temps_epreuve, colle.matiere_id, colle.dateCreation, colle.ordre, colle.discr
FROM colle";
$stmt = $db->prepare($query);
$stmt->execute();
$query2 = "INSERT INTO banque_colle_qc (id)
SELECT colle_qc.id
FROM colle_qc";
$stmt = $db->prepare($query2);
$stmt->execute();
return true;
}
public function archiveQC() {
$db = $this->em->getConnection();
$query = "INSERT INTO banque_qc (id, titre, id_colle, ordre, qcPere, enonce, donnees, item1, item2, item3, item4,
item5, corrige_item1, corrige_item2, corrige_item3, corrige_item4, corrige_item5, item1_vrai,
item2_vrai, item3_vrai, item4_vrai, item5_vrai, item1_annule, item2_annule, item3_annule,
item4_annule, item5_annule, multiple_choices, inclu)
SELECT qc.id, qc.titre, qc.id_colle, qc.ordre, qc.qcPere, qc.enonce, qc.donnees, qc.item1, qc.item2,
qc.item3, qc.item4, qc.item5, qc.corrige_item1, qc.corrige_item2, qc.corrige_item3, qc.corrige_item4,
qc.corrige_item5, qc.item1_vrai, qc.item2_vrai, qc.item3_vrai, qc.item4_vrai, qc.item5_vrai,
qc.item1_annule, qc.item2_annule, qc.item3_annule, qc.item4_annule, qc.item5_annule,
qc.multiple_choices, qc.inclu
FROM qc
ORDER BY qc.qcPere ASC";
$stmt = $db->prepare($query);
$stmt->execute();
return true;
}
public function archivePassages() {
$db = $this->em->getConnection();
$query = "INSERT INTO banque_passer_colle (colle_id, dateDebut, note)
SELECT passer_colle.colle_id, passer_colle.dateDebut, passer_colle.note
FROM passer_colle";
$stmt = $db->prepare($query);
$stmt->execute();
return true;
}
public function archiveReponses() {
$db = $this->em->getConnection();
$query = "INSERT INTO banque_reponse (id, discr)
SELECT reponse.id, reponse.discr
FROM reponse
WHERE discr='reponseQC'";
$stmt = $db->prepare($query);
$stmt->execute();
$query2 = "INSERT INTO banque_reponse_qc (id, question, A, B, C, D, E, note)
SELECT reponse_qc.id, reponse_qc.question, reponse_qc.A, reponse_qc.B, reponse_qc.C, reponse_qc.D,
reponse_qc.E, reponse_qc.note
FROM reponse_qc";
$stmt = $db->prepare($query2);
$stmt->execute();
return true;
}
public function archiveStats() {
$db = $this->em->getConnection();
$query = "INSERT INTO banque_statistiquecolle (id, colle_id, effectif, moyenne, mediane, note100, major, minor)
SELECT sc.id, sc.colle_id, sc.effectif, sc.moyenne, sc.mediane, sc.note100, sc.major, sc.minor
FROM statistiquecolle_groupe scg
LEFT JOIN statistiquecolle sc ON sc.id = scg.statistiquecolle_id
WHERE scg.groupe_id = 1
AND sc.id NOT IN (SELECT sc1.id
FROM statistiquecolle_groupe scg1
LEFT JOIN statistiquecolle sc1 ON sc1.id = scg1.statistiquecolle_id
WHERE scg1.groupe_id != 1)";
$stmt = $db->prepare($query);
$stmt->execute();
$query2 = "INSERT INTO banque_statistiquequestion (id, question_id, moyenne, nbReponseTot, nbReponseA, nbReponseB,
nbReponseC, nbReponseD, nbReponseE)
SELECT sq.id, sq.question_id, sq.moyenne, sq.nbReponseTot, sq.nbReponseA, sq.nbReponseB, sq.nbReponseC,
sq.nbReponseD, sq.nbReponseE
FROM statistiquequestion_groupe sqg
LEFT JOIN statistiquequestion sq ON sq.id = sqg.statistiquequestion_id
WHERE sqg.groupe_id = 1
AND sq.id NOT IN (SELECT sq1.id
FROM statistiquequestion_groupe sqg1
LEFT JOIN statistiquequestion sq1 ON sq1.id = sqg1.statistiquequestion_id
WHERE sqg1.groupe_id != 1)";
$stmt = $db->prepare($query2);
$stmt->execute();
$query3 = "INSERT INTO banque_repartitioncolle (id, statColle_id, note, nombre, percentOfEffectif)
SELECT rc.id, rc.statColle_id, rc.note, rc.nombre, rc.percentOfEffectif
FROM repartitioncolle rc
WHERE rc.statColle_id IN (SELECT bsc.id
FROM banque_statistiquecolle bsc)";
$stmt = $db->prepare($query3);
$stmt->execute();
$query4 = "INSERT INTO banque_repartitionquestion (id, statQuestion_id, note, nombre, percentOfEffectif)
SELECT rq.id, rq.statQuestion_id, rq.note, rq.nombre, rq.percentOfEffectif
FROM repartitionquestion rq
WHERE rq.statQuestion_id IN (SELECT bsq.id
FROM banque_statistiquequestion bsq)";
$stmt = $db->prepare($query4);
$stmt->execute();
return true;
}
I've been doing a database migration recently, and have found that the easiest method (for me) is to do everything in SQL. It's a bit laborious, but it worked okay for my project
First drop all the constraints
# Table1.field1
ALTER TABLE Table1 DROP FOREIGN KEY FK_Table1_field1;
ALTER TABLE Table1 DROP INDEX IDX_Table1_field1;
# Table1.field2
ALTER TABLE Table1 DROP FOREIGN KEY FK_Table1_field2;
ALTER TABLE Table1 DROP INDEX IDX_Table1_field2;
Then add all the SQL you have to move the data into the new tables.
Then drop all the old tables
DROP TABLE IF EXISTS Table1;
DROP TABLE IF EXISTS Table2;
Then Add all the constraints back in
ALTER TABLE Table1
ADD INDEX IDX_Table1_field1 (field1 ASC);
ALTER TABLE Table1
ADD CONSTRAINT FK_Table1_field1
FOREIGN KEY (field1)
REFERENCES OtherTable (xxxx)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
I kept each step in it's own sql file, so for this example there would be 4 sql files, might be easier to manage if you split up the data move step into more than one file as well.

updating the data using implode in php

please help me out and sorry for my bad English,
I have fetch data , on basis of that data I want to update the rows,
Follows my code
I fetched data to connect API parameters
<?php
$stmt = $db->stmt_init();
/* publish store for icube*/
$stmt->prepare( "SELECT id,offer_id,name,net_provider,date,visible,apikey,networkid FROM " ."affilate_offer_findall_icube WHERE visible='1' ");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result( $id, $offer_id, $name, $net_provider, $date, $visible,$apikey,$networkid);
$sql = array();
if($rows>0)
{
while($info = $stmt->fetch() ) {
$jsondataicube = file_get_contents('filename/json?NetworkId='.$networkid.'&Target=Affiliate_Offer&Method=getThumbnail&api_key='.$apikey.'&ids%5B%5D='.$offer_id.'');
$dataicube = json_decode($jsondataicube, true);
foreach($dataicube['response']['data'][0]['Thumbnail'] as $key=>$val)
{
$offer_id = $dataicube['response']['data'][0]['Thumbnail']["$key"]['offer_id'];
$display = $dataicube['response']['data'][0]['Thumbnail']["$key"]['display'];
$filename = $dataicube['response']['data'][0]['Thumbnail']["$key"]['filename'];
$url = $dataicube['response']['data'][0]['Thumbnail']["$key"]['url'];
$thumbnail = $dataicube['response']['data'][0]['Thumbnail']["$key"]['thumbnail'];
$_filename = mysqli_real_escape_string($db,$filename);
$_url = mysqli_real_escape_string($db,$url);
$_thumbnail = mysqli_real_escape_string($db,$thumbnail);
$sql[] = '("'.$offer_id.'","icube","'.$_thumbnail.'","'.$_url.'")';
}
}
As I store values which have to be inserted in 'sql'
now
$stmt->prepare( "SELECT offer_id FROM " ."affilate_offer_getthumbnail_icube ORDER BY 'offer_id' ASC");
$stmt->execute();
mysqli_stmt_execute($stmt); // <--------- currently missing!!!
mysqli_stmt_store_result($stmt);
$rows = mysqli_stmt_num_rows($stmt);
$stmt->bind_result($offer_id);
$sqlimplode = implode(',', $sql);
if($rows>0)
{
$query = "UPDATE affilate_offer_getthumbnail_icube WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}`
`
Insert query working well,but how can I update all the data like insert query ?
My Answer is refering to a "set and forget"-strategy. I dont want to look for an existing row first - probably using PHP. I just want to create the right SQL-Command and send it.
There are several ways to update data which already had been entered (or are missing). First you should alter your table to set a problem-specific UNIQUE-Key. This is setting up a little more intelligence for your table to check on already inserted data by its own. The following change would mean there can be no second row with the same value twice in this UNIQUE-set column.
If that would occur, you would get some error or special behaviour.
Instead of using PHPMyAdmin you can use this command to set a column unique:
ALTER TABLE `TestTable` ADD UNIQUE(`tablecolumn`);
After setting up your table with this additional intelligence, you alter your Insert-Command a little bit:
Instead of Insert you can drop and overwrite your Datarow with
REPLACE:
$query= "REPLACE INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100) VALUES (".$sqlimplode.")";
See: Replace Into Query Syntax
Secondly you can do this with the "On Duplicate Key"-Commando.
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
$query= "INSERT INTO affilate_offer_getthumbnail_icube
(offer_id, net_provider,logo2020,logo100)
VALUES (".$sqlimplode.")
ON DUPLICATE KEY UPDATE net_provider = ".$newnetprovider.",
logo2020 = ".$newlogo2020.",
logo100 = ".$newlogo100.";";
Note: I think you missed some ( and ) around your $sqlimplode. I always put them around your implode. Maybe you are missing ' ' around strings as well.
Syntax of UPDATE query is
UPDATE table SET field1 = value1, field2 = value2 ...
So, you cannot pass your imploded array $sql to UPDATE query. You have to generate another sql-string for UPDATE query.
This is clearly incorrect:
$query = "UPDATE affilate_offer_getthumbnail_icube
WHERE offer_id='".$offer_id."' SET '".$sqlimplode."'";
If the intention is to INSERT offer_id='".$offer_id."' and then UPDATE ... SET offer_id = '".$sqlimplode."'";
You have to use two separate queries, one for INSERT and then another one for UPDATE
An Example:
$query = "INSERT INTO affilate_offer_getthumbnail_icube
(col_name) VALUES('".$col_Value."')";
//(execute it first);
$query2 = "UPDATE affilate_offer_getthumbnail_icube SET
col_name= '".$col_Value."'" WHERE if_any_col = 'if_any_Value';
//(execute this next);
Try this:
$sqlimplode = implode(',', $sql);
if($rows>0)
{
/*$fields_values = explode(',',trim(array_shift($sql), "()"));
$combined_arr = array_combine(['offer_id','net_provider','logo2020','logo100'],$fields_values);
$sqlimplode = implode(', ', array_map(function ($v, $k) { return $k . '=' . $v; }, $combined_arr, array_keys($combined_arr))); */
$query = "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode." ON duplicate key update net_provider = values(net_provider),logo2020 = values(logo2020),logo100 = values(logo100)";
$stmt->prepare( $query);
$execute = $stmt->execute();
}
else
{
$sqlimplode = implode(',', $sql);
$query= "INSERT INTO affilate_offer_getthumbnail_icube(offer_id, net_provider,logo2020,logo100) VALUES".$sqlimplode;
$stmt->prepare( $query);
$execute = $stmt->execute();
}

how to do more than query on the same record?

I have this php file to deal with my sql, I want to make many statement on one record in the database
for examole I have this query :
$query = mysql_query("SELECT bloodGroup,quantity,bank_id FROM medical_bank_notification WHERE seen=1");
I want to make all the records which were selected in the $query to have the field seen=0 after it has been selected, so I thought that I have to know all the IDs from the first query and then write another query:
$sql2 = "INSERT INTO medical_bank_notification (seen) VALUES (0) WHERE ID=_????_";
use mysqli_multi_query($con,$query)
$query = "INSERT INTO table1 (column1,column2,column3)
VALUES (value1,value2,value3);";
$query .= "INSERT INTO table2 (column1,column2,column3)
VALUES (value1,value2,value3);";
//excute query
if(mysqli_multi_query($con,$query))
{
while (mysqli_next_result($con) && mysqli_more_results($con))
{
if ($resSet = mysqli_store_result($con)) { mysqli_free_result($resSet); }
if (mysqli_more_results($con)){ }
}
echo 'success';
}

Unable to insert into MySQL for select values

I have a web application in which students are divided into "batches".
I am trying to insert student for particular batch and the batch will be chosen by user by select option. After that student is added to the particular batch, he/she will be added to stdhold table. However, it is only inserting for the first selected value of select option.
<?php
function specialCOn() {
$connew = mysqli_connect("localhost","root","");
$db = mysqli_select_db($connew,'mcqs');
return($connew);
}
if (isset($_POST['add']))
{
$namestd=$_POST['std_name'];
$batchstd=$_POST['batch'];
$FNAME=$_POST['f_name'];
$query3 = "INSERT INTO `$batchstd` VALUES('','$namestd','$FNAME')";
$rsq3 = mysqli_query(specialCOn(),$query3);
mysqli_close(specialCOn());
$queryrollno = "select rollno from `$batchstd` order by rollno desc";
$rsqrollno = mysqli_query(specialCOn(),$querrollno);
$getrollno = mysqli_fetch_array($rsqrollno);
$rollnoto = $getrollno[0];
echo "<script>alert('$batchstd')</script>";
echo "<script>alert('$rollnoto')</script>";
mysqli_close(specialCOn());
//Problem is here
$querystdhold = "INSERT INTO stdhold VALUES ($rollnoto, '$namestd', '$FNAME', '$batchstd')";
$rsqhold = mysqli_query(specialCOn(),$querystdhold);
mysqli_close(specialCOn());
if ($rsq3&&$rsqhold)
{
echo "<script> alert('Student Added.');
window.location.assign('addstudent.php');
</script>";
//header('Location:addstudent.php');
}
else
{
echo "<script> alert('You Havenot added Student.');
window.location.assign('addstudent.php');</script>";
}
}
?>
Try use this :
$db = new mysqli("host","user","pw","database");
$stmt = $db->prepare("INSERT INTO ? (col1,col2,col3) VALUES('',?,?)");
$stmt->bind_param('sss', $_POST['batch'], $_POST['std_name'], $_POST['f_name']);
$stmt->execute();
For the detail example you need to read the #Amber Answer how to create secured prepared statement.
Hope this'll help you.
Try specifying the column names in your insert query:
INSERT INTO stdhold (col1, col2, col3, col4) VALUES ($rollnoto, '$namestd', '$FNAME', '$batchstd');
For reference see the MySQL Insert documentation.

Updating a form entry in php/mysql with checkboxes?

How can I allow the user submitting a form, to update his entry on "re-submission"
for example
12345678910 (unique id) , submitted the form with selections,
12345678910 , re-submitted with new selections
what's the function responsible for "automatically" updating such kind of form entries.
I know that I can use a check if the entry exists, but how do I update it if it exists and insert it in a new row if it doesn't ...
function checkstudentid($studentid)
{
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
if(mysql_fetch_array($result) !== false)
....
// I want to add the entry here since it doesn't exist...with checkboxes
// else , I want to update if it already exists
}
Now I'm also not completely positive if the above code will work...but this is what I have for starters, if there is any other way or if the method I'm using is "wrong" , I would appreciate the heads up...or if what I'm trying to is even possible (the way I'm doing it)...
NOTES
I only have one php file which the form submits to.
I am not using a login/registration system
I do not want to display all the data in a table using HTML, just an
"automatic" update if the studentid already exists in the table
If I were using a deprecated method to interact with a database, I would probably just do this:
<?php
function checkstudentid($studentid) {
$con = connectvar();
mysql_select_db("database1", $con);
$result = mysql_query(
"SELECT * FROM table WHERE studentid='$studentid' LIMIT 1");
$query = '';
if (mysql_num_rows($result) > 0) {
$query = "UPDATE table SET column1='$value_one', column2='$value_two' WHERE studentid='$studentid'";
} else {
$query = "INSERT INTO table VALUES('$new_id', '$value_one', '$value_two')";
}
if (mysql_query($query)) {
return true;
} else {
return false;
}
}
?>
But then again, I would use PDO to interact with the DB.
Here is a simple PDO example (you just have to write the function to return the connection):
<?php
function checkstudentid($studentid) {
$update = false;
$dbh = formPDOConnection();
$query = "SELECT studentid FROM table WHERE studentid=:id";
$stmt = $dbh->prepare($query);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
if ($stmt->execute()) {
if ($stmt->rowCount()) {
$update = true;
}
} else {
return 'failure to execute query';
}
// if we just need to update
if ($update) {
$update = "UPDATE table SET value1=:v1,
value2=:v2 WHERE studentid=:id";
$stmt = $dbh->prepare($update);
$stmt->bindValue(':id', $studentid, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
} else {
$insert = "INSERT INTO table VALUES(:id,:v1,v2)";
$stmt = $dbh->prepare($insert);
$stmt->bindValue(':id', $new_id, PDO::PARAM_STR);
$stmt->bindValue(':v1', $value_one, PDO::PARAM_STR);
$stmt->bindValue(':v2', $value_two, PDO::PARAM_STR);
}
return $stmt->execute();
}
?>
Save yourself a headache and stop using mysql_*
You can use INSERT... ON DUPLICATE KEY UPDATE... on your mysql code instead use the logic in your PHP.
Here's a sample:
INSERT INTO `category` (`id`, `name`) VALUES (12, 'color')
ON DUPLICATE KEY UPDATE `name` = 'color';
Reference: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html

Categories