Hello all,
I am working on a site were a member can send message to all of his/her friends ..
so all of their friends are stored in an array like:
$selectfrnds=mysql_query("select sender_id,receiver_id from fk_friends where (sender_id='$id' or receiver_id='$id') and friendtofriend='freq' ");
$friendis=array();
I have imploded the query into a variable and now all their friends are represented:
$frndsall='4','8','2','12','13','14','15','16','18','19','21','23','24','27','35','36','40','43','29','45','44','38','46','22','1'
so I just want to ask: How do I insert query that will send a message to all these ids?
I want something like:
insert into tablename (message,id// id of friend ) values ('$message//this is same','$xyz// which is stored into varialbe $frndsall one by one it should insert with all the values')
any help please...
Use Prepared Statements in a foreach loop:
$stmt = $pdo->prepare(
"INSERT INTO tablename (message, id) VALUES (:message, :id)");
$stmt->bindParam(':message', $message);
$stmt->bindParam(':id', $id);
foreach ($frndsall as $frndId) {
$id = $frndId;
$stmt->execute();
}
check out php foreach statements (http://www.php.net/manual/en/control-structures.foreach.php) - that should be what you're looking for.
It's possible to do bulk insert by first preparing a select statement that produces the desired result set to be inserted, then prefixing INSERT into .
Example
INSERT INTO tablename (message, id)
SELECT '$message', receiver_id
FROM fk_friends
WHERE (sender_id='$id' or receiver_id='$id') AND friendtofriend='freq'
If your database abstraction layer supports prepared statements, something like this is probably the best way to do this query.
$db->query($db->prepare('
INSERT INTO tablename (message, id)
SELECT ?, receiver_id
FROM fk_friends
WHERE (sender_id=? or receiver_id=?) AND friendtofriend=?
'), array($message, $id, $id, 'freq')));
Otherwise, if not using prepared statements, be sure to properly escape all data you insert into the query before querying it from the database, using the relevant escaping function for your method of accessing the database.
Hope that helps.
You can do Insert in foreach, but this solution will bad on real project, where user will have more than 3k friends.
Here is a question of database architecture in my mind.
You say:
member can send message to all of his/her friends
If you want to add possibility to send a message only to all, will be better to use separate table like
`mass_messages`
id (int 11)
sender_id (int 11)
message (text)
send_date (timestamp)
Also you can create another table to store friends who already read your message.
But this way not useful if you try to send message to all except for a few friends.
Related
I have written my sql below and it works. As I've set my particulars_id to autoincrement, i have to use Last_Insert_ID() in order for the database to use the next id using auto increment. However, i would like to store that value into a php variable. Is that possible?
$addquery = "INSERT INTO Particulars (Particulars_ID, Name, Identification_Number, Number, Nationality, Status, Remarks)
VALUES(LAST_INSERT_ID(),'$_POST[newname]', '$_POST[newic]','$_POST[newnumber]','$_POST[newnationality]','$_POST[newstatus]','$_POST[newremarks]')";
When you insert a row into a table that has an AUTO_INCREMENT field that field will be incremented automatically as the name implies. You don't need to tell MySQL to increment it, you don't have to provide a value for the auto-increment field at all.
So to begin with, remove the call to LAST_INSERT_ID() from your query:
$addquery = "INSERT INTO Particulars (Name, Identification_Number, Number, Nationality, Status, Remarks)
'$_POST[newname]', '$_POST[newic]','$_POST[newnumber]','$_POST[newnationality]','$_POST[newstatus]','$_POST[newremarks]')";
Notice how I completely removed the Particulars_ID from the query.
Second, this is not directly related to your question but your query is vulnerable to SQL Injection. When accepting user input you should avoid concatenating it to your query, instead use Prepared Statements and modify your query like this:
$addquery = "INSERT INTO Particulars (Name, Identification_Number, Number, Nationality, Status, Remarks)
VALUES(?,?,?,?,?,?)";
You can then prepare a statement and bind the values from $_POST. This essentially sanitizes user input. Read more about prepared statements here
START OF EDIT
An example of binding the real values to the ? placeholders using PDO:
//First prepare the statemt
$db->prepare("INSERT INTO Particulars (Name, Identification_Number, Number,Nationality, Status, Remarks)
VALUES(?,?,?,?,?,?)";
//Start binding values to placeholders
$db->bindValue(1, $_POST['name']);
$db->bindValue(2, $_POST['Identification_Number'];
$db->bindValue(3, $_POST['Number'];
//Bind the rest of the values in the same way
END OF EDIT
About the id of the last inserted row you will need to run a separate query to get it. So after you run the above query and if insertion is successful you can
run a query like this:
SELECT LAST_INSERT_ID() AS id FROM Pariculars
I am trying to ignore an INSERT query if the two values, Answer1Text and Answer2Text are already in the database, but still get the id (called AnswerID (Primary Key) from the row? How can I do this?
My code:
$stmt = $conn->prepare("INSERT INTO answers (Answer1Text, Answer2Text) VALUES (?, ?)");
$stmt->bind_param('ss', $text1, $text2);
$stmt->execute();
$answerid = $stmt->insert_id;
Table of importance:
answers: AnswerID(PK), Answer1Text, Answer2Text
I have tried looking at ON DUPLICATE KEY UPDATE but I neither understand how to use it, nor do I think it is the right choice.
The best approach is to query your database first using a SELECT query: does the data already exist? If so, pull out the ID and use that in place of the insert ID; if not, insert a new row. You're right: ON DUPLICATE KEY UPDATE is wrong for this.
Is it possible to INSERT a row, and simultaneously set one of the fields to contain the inserted row's ID? (the "self" id)
I'm trying to avoid using multiple queries if possible (it would be 3 queries in total otherwhise)
Something like this (but probably not):
INSERT INTO thetable (email, phone, activationkey) VALUES ($email, $phone, CONCAT(THIS_NEW_ID, md5($activation) )
Why would you want to store duplicated data?
You could change your table structure and just run:
INSERT INTO thetable (email, phone, activation_suffix)
VALUES ($email, $phone, md5($activation))
And then you have all the data you need.
You can always concat when you query the table:
SELECT CONCAT(id, activation_suffix) activationkey
FROM thetable
WHERE ...
UPDATE
On second thoughts, do you really need the id as part of the activationkey?
I wouldn't want to give any user the id for their record in my table unless it is hashed/encrypted.
This question already has answers here:
MySQL Insert into multiple tables? (Database normalization?) [duplicate]
(7 answers)
Closed 9 years ago.
How do I insert from 1 form into 2 tables?
I want to submit into tables: gallery and cat.
This is the code I have for just submitting into gallery. How do I add info to the cat table simultaneously?
$sql = 'INSERT INTO gallery (image_url, image_name, image_description)
VALUES (?, ?, ?)';
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param('sss', $_FILES['upload']['name'], $_POST['image_name'],
$_POST['image_description']);
$OK = $stmt->execute();
}
What do I do with this:
$sql_2 = 'INSERT INTO cat (cat_name) VALUES (?)';
After the code you have above, just initialize a new statement, bind it, and execute. You can use the existing connection ($conn). The $sql and $stmt variables have already done their job by inserting into the first table, so just reset them for the second insert.
... your code as posted above, followed by:
$sql = 'INSERT INTO cat (cat_name) VALUES (?)';
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', put your cat_name value here);
$OK = $stmt->execute();
}
The important thing to remember is that the second insert is just like the first: you have to initialize it, bind it, and execute it.
You should use transactions as demonstrated here.
No, you can't insert into multiple tables in one MySQL command. You can however use transactions.
BEGIN
INSERT INTO users (username, password)
VALUES('test', 'test')
INSERT INTO profiles (userid, bio, homepage)
VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;
Have a look at LAST_INSERT_ID to reuse autoincrement values.
Edit: you said "After all this time trying to figure it out, it still doesn't work. Can't I simply put the just generated ID in a $var and put that $var in all the MySQL commands?"
Let me elaborate: there are 3 possible ways here:
1/ Is the code you see above. This does it all in MySQL, and the LAST_INSERT_ID in the second statement will automatically be the value of the autoincrement-column that was inserted in the first statement.
Unfortunately, when the second statement itself inserts rows in a table with an auto-increment column, the LAST_INSERT_ID will be updated to that of table 2, and not table 1. If you still need that of table 1 afterwards, we will have to store it in a variable. This leads us to ways 2 and 3:
2/ Will stock the LAST_INSERT_ID in a MySQL variable:
A/ INSERT B/ SELECT LAST_INSERT_ID into #mysql_variable_here C/ INSERT INTO table2 (#mysql_variable_here D/ INSERT INTO table3 (#mysql_variable_here ...
3/ Will stock the LAST_INSERT_ID in a php variable (or any language that can connect to a database, of your choice):
A/ INSERT B/ Use your language to retrieve the LAST_INSERT_ID, either by executing that literal statement in MySQL, or using for example php's mysql_insert_id() which does that for you C/ INSERT ()
I'm learning PHP and MySQL and I'm creating a movies website for learning purposes.
I want to insert variables and arrays containing movie info into a database but in different tables.
This is what I have right now:
include('inc/connection.php');
$conn = dbConnect();
// create SQL
$sql = 'INSERT INTO movies (movieid, title, year, runtime, plot)
VALUES(?, ?, ?, ?, ?)';
// initialize prepared statement
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
// bind parameters and execute statment
$stmt->bind_param('isiis', $movieid, $title, $year, $runtime, $plot);
$stmt->execute();
}
This insert the variables into the movies table.
But I also need to insert (at the same time) the genres of the movie, the actors, languages, etc... they are in arrays and go into different tables (and maybe also in different rows). For example the array containing the genres (Action, Crime, Drama) genres in the genres table, and the actors in the actors table and so on... I then will use many-to-many and one-to-many tables to display the info.
Can someone explain to me how to do this?? I need to connect to the database multiple times?? I need loops? I'm really new to PHP and MySQLi so please try to explain as much as you can.
Thanks.
INSERT supports only one table at a time, so you'll certainly have to execute multiple INSERT statements if you have complex data that goes into multiple tables.
If you've inserted a specific $movieid value to movies then you know what value you need to insert to the rows of the other tables, to satisfy referential integrity (pseudocode follows, not fully functional example):
$movies_sql = 'INSERT INTO movies (movieid, title, year, runtime, plot)
VALUES(?, ?, ?, ?, ?)';
// execute ($movieid, ...)
$actors_sql = 'INSERT INTO movie_actors (movieid, actorid)
VALUES (?, ?)';
foreach ($actorlist as $actorid) {
// execute ($movieid, $actorid)
}
$lang_sql = 'INSERT INTO movie_languages (movieid, language)
VALUES (?, ?)';
foreach ($languagelist as $language) {
// execute ($movieid, $language)
}
If your movies table uses an AUTO_INCREMENT primary key, then you can get the value generated during the first INSERT either by calling $mysqli->insert_id(), or by using the builtin function LAST_INSERT_ID().
$actors_sql = 'INSERT INTO movie_actors (movieid, actorid)
VALUES (LAST_INSERT_ID(), ?)';
foreach ($actorlist as $actorid) {
// execute ($actorid) -- only one param in this INSERT
}
Note that LAST_INSERT_ID() reports the most recent auto-generated value during your current session, so if you insert to another table that uses an auto primary key, the value changes. But the value reported is stable during your sessions; it does not change if another client session is doing inserts concurrently.
You only need one database connection
Yes you do need loops
Use an auto_increment primary key field in each table, and then use $stmt->insert_id() to extract the value after each insert
If you can, use InnoDB on the MySQL server to get transaction support, and then commit relevant updates together, to ensure that your database is consistent if your script drops out mid-way through an update. The more common MyISAM database table format doesn't support transactions.
You don't need to use more than one database connection - in fact that's what you shouldn't do at all, because you couldn't group your inserts into one atomic transaction.
What you should do (abstract) is:
BEGIN;
INSERT INTO Genres...;
INSERT INTO Actors...;
INSERT INTO othertable....;
and so on, for referenced columns/tables.
INSERT INTO Movies....;
COMMIT;
This way you should always have a consistent dataset.
you are probably going after foreign keys - use one ID from the base table to identify other relations in other table (use movieid in other table to identify what movie the other values belong to etc.)