I am creating a forum service ( https://www.orbitrondev.com/forum/ )
When someone creates a new thread it will execute:
// Example values
$UserID = 23123;
$ForumID = 1;
$ThreadName = 'Example title';
$sQuery = 'INSERT INTO threads (user_id, board_id, topic, time, lastPostUserId, lastPostTime)
VALUES ("' . $UserID . '", "' . $ForumID . '", "' . $ThreadName . '", "' . $time . '", "' . $UserID . '", "' . $time . '")';
The ID is in the column thread_id
Now I have to get the ID (thread_id) of the inserted row. So I can create a post, and to create a post I need the ID.
I thought about getting the last inserted thread id an adding 1 so I have the id, but SQL looks finer :P
How can I know the thread_id value for the newly inserted row?
You should use mysqli::$insert_id.
Where $mysqli is your connection;
$result = $mysqli->query($sQuery);
$lastid = $mysqli->insert_id;
Although you should use prepared statements when inserting data into the database.
Note: You need to have an auto incremented ID field in the database for this to work.
You have;
$oResult = $Database->query($sQuery);
$ThreadID = $oResult->insert_id;
which will not work.
You should use the connection to find the last inserted ID, like this;
$oResult = $Database->query($sQuery);
$ThreadID = $Database->insert_id;
Hope this helps.
You can retrieve the most recent AUTO_INCREMENT value with the
LAST_INSERT_ID() SQL function or the mysql_insert_id() C API function.
These functions are connection-specific, so their return values are
not affected by another connection which is also performing inserts
http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
mysqli::$insert_id -- mysqli_insert_id — Returns the auto generated id
used in the last query
http://php.net/manual/en/mysqli.insert-id.php
Related
how can i update and insert together
require_once ('database.php');
$name = mysql_real_escape_string ($_REQUEST["name"]);
$course = mysql_real_escape_string ($_REQUEST["course"]);
$email = mysql_real_escape_string ($_REQUEST["email"]);
$contact = mysql_real_escape_string ($_REQUEST["contact"]);
$Date = mysql_real_escape_string ($_REQUEST["Date"]);
$sql = "SELECT * FROM registerlist WHERE name = '" . $name . "'";
$result = mysql_query ($sql, $dbconn);
if (mysql_num_rows ($result) > 0) {
$resultStr = header("Location:blog.php");
} else {
$result = "SELECT * FROM courselist WHERE cname = '" . $course
. "'";
$row=mysql_fetch_row($result);
$sql = "INSERT INTO registerlist (name, Course, Email, Contact,
Date) VALUES ('" . $name . "', '" . $course . "', '" . $email . "', '" .
$contact . "','" . $date . "')";
$result1= mysql_query($sql, $dbconn);
$result =mysql_query("UPDATE courselist SET $Row['slot'] =
'$Row['slot'] - 1 '");
if ($result1) {
$resultStr = header("Location:blog.php");
}
}
echo json_encode($resultStr);
if the person register the course, the course slot will subract by 1 and student document will be insert into registerlist database.
I hope I did understand correctly: You want to update the courselist table at the same time a record was insert into the registerlist table? This can be done using triggers (https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html , IF both databases run at the same SQL server) and/or table locks (https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html):
Without trigger
Lock table courselist
Insert the record to registerlist
Update table courselist
Release table courselist
With trigger
You need a trigger that locks the table courselist before writing to the registerlist table, and a trigger that updates courselist and releases the lock after writing to registerlist.
In this case you only insert the record into registerlist from your PHP code, and the table locking and courselist update is being done by the triggers within the SQL server.
In any case you can't write to both tables at the same time, there is no SQL statement to do that. But with locks you can simulate such a behavior.
When defining the target table of a SQL statement, you may prepend the tables database name like databaseName.tableName, if the Connection uses a different database per Default.
But aynber from the comments is absolutely right - you should move away from mysql_* asap!
Edit: This SQL example should show how table locking is working (all information about that can be found in the MySQL documentation from the link above):
LOCK TABLES courselist WRITE;
INSERT INTO registerlist …;
UPDATE courselist …;
UNLOCK TABLES;
You'll Need a WRITE lock, since you're going to write to the table. Other reading, writing or locking statements from other sessions are blocked until you release the lock.
A READ lock would prevent the table from being modified by any session. Writing (and write locking) attempts are blocked until you release the lock and all other READ locks from other sessions are released, too.
Here's the table structure
CREATE TABLE IF NOT EXISTS `result` (
`res_id` int(11) NOT NULL AUTO_INCREMENT,
`s_id` int(10) NOT NULL,
`i_id` int(6) NOT NULL,
`r_status` text NOT NULL,
`r_score` decimal(6,0) NOT NULL,
PRIMARY KEY (`res_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
I've searched for a solution and have tried on different occasions, building the table from scratch, drop and import it back, checked the index. As you can see, I've renamed the id to res_id but when I run it on the browser the error still shows r_id.
If it makes a difference, when the id is not set to auto increment, the same error pops up.
Here's the code snippet for the page where I want to insert into the database.
//retrieve existing r_id
$sql_res = "SELECT res_id FROM result ORDER BY res_id DESC LIMIT 1";
$query_res = mysql_query($sql_res) or die("MySQL Error: " . mysql_error());
$data_res = mysql_fetch_assoc($query_res);
$resid_count = $data_res['res_id']+1;
//echo "<br>Result: " . $resid_count;
// insert result to table
$sql_result = "INSERT INTO result (res_id, r_score, s_id, i_id) VALUES ('" . $resid_count . "', '" . $correct . "', '" . $id . "', '" . $ins_id . "')";
mysql_query($sql_result) or die ("Error: " . mysql_error());
EDIT: I changed the code like you guys suggested. Took the res_id out from the INSERT. It still says duplicate entry for r_id. I went ahead for trial and error and created another table 'score' with the same structure to replace 'result'. Was wondering if the same table name was giving it problem (could running the page many times cause this?). Same outcome with the score table.
Any help would be greatly appreciated. I'm stuck here and cannot proceed with my project. Thanks.
Atikah
Since res_idis AUTO_INCREMENTI suggest that you replace your insert query by this:
$sql_result = "INSERT INTO result (r_score, s_id, i_id) VALUES ('". $correct . "', '" . $id . "', '" . $ins_id . "')";
try this
$sql_result = "INSERT INTO result ( r_score, s_id, i_id) VALUES ( '" . $correct . "', '" . $id . "', '" . $ins_id . "')";
res_id will be automatically inserted without your inserting
EDIT.
If you want just insert then you dont need those lines , just remove them, because you are using them for knowing the last res_id . since res_id as i said before its auto_increment. it will increment automatically
$sql_res = "SELECT res_id FROM result ORDER BY res_id DESC LIMIT 1";
$query_res = mysql_query($sql_res) or die("MySQL Error: " . mysql_error());
$data_res = mysql_fetch_assoc($query_res);
$resid_count = $data_res['res_id']+1;
Make sure you don't use apostrophes in your SQL where you use numerics (int). This could cause trouble. And res_id should not be involved at all, because that's the point with having autoincremental columns (You don't have search for the next id in the database with PHP-code, DB takes care of that)
Your code could be translated into two lines:
$sql_result = "INSERT INTO result (r_score, s_id, i_id) VALUES (" . $correct . ", " . $id . ", " . $ins_id . ")";
mysql_query($sql_result) or die ("Error: " . mysql_error());
OR (variables inside quotes gives the actual values)
$sql_result = "INSERT INTO result (r_score, s_id, i_id) VALUES ($correct, $id, $ins_id)";
mysql_query($sql_result) or die ("Error: " . mysql_error());
and of course - don't use mysql_* - functions, cause they're deprecated. Use PDO or Mysqli instead with parameters so you could avoid SQL injection in a safe way. The code you've got is vulnerable to SQL injections.
$tSQL = "insert into events(title,start,end,allday,url,customerid) VALUES(\"" . $_POST['title'] . "\", FROM_UNIXTIME($epochstart), FROM_UNIXTIME($epochend), \"$allday\", \"$url\", \"$customerid\")";
$mysqli->multi_query($tSQL);
$lasterror = $mysqli->error;
$tSQL = "update events set url = \"details.php?\"" . mysql_insert_id() . " where idevents = \"$eventid\"";
$row = $mysqli->multi_query($tSQL);
$lasterror = $mysqli->error;
echo print_r($tSQL);
My insert statement for sure does insert the record however mysql_insert_id() keeps returning 0. It should not be this way because there is an auto incremented primary key in that events table and that is running fine as well. Any suggestions on how to get the last inserted ID?
Your query is executed via mysqli, so the mysql function would not hold the inserted ID. Instead, use the mysqli version:
$id = $mysqli->insert_id;
Becasue you are using mysqli and not mysql,
Simply replace mysql_insert_id() with mysqli_insert_id() if using Procedural style
Or replace it with $mysqli->insert_id if using Object Oriented Style
Since you are using mysqli extension, change
$tSQL = "update events set url = \"details.php?\"" . mysql_insert_id() . " where idevents = \"$eventid\"";
to
$tSQL = "update events set url = \"details.php?\"" .$mysqli->insert_id. " where idevents = \"$eventid\"";
Because your are using mysqli which is an improvement version of mysql.
Use mysqli->insert_id instead of mysql->insert_id()
$tSQL = "insert into events(title,start,end,allday,url,customerid) VALUES(\"" . $_POST['title'] . "\", FROM_UNIXTIME($epochstart), FROM_UNIXTIME($epochend), \"$allday\", \"$url\", \"$customerid\")";
$mysqli->multi_query($tSQL);
$lasterror = $mysqli->error;
$lastInsId=$mysqli->insert_id();
$tSQL = "update events set url = \"details.php?\"" . $lastInsId . " where idevents = \"$eventid\"";
$row = $mysqli->multi_query($tSQL);
$lasterror = $mysqli->error;
echo print_r($tSQL);
I have a SQL query like
$result = mssql_query("INSERT into CALLER
( status, media, media_2, first_name, last_name, street_address, city,
state, zipcode, home_phone_no, mobile_phone_no,email, problem,
medical_condition, comments, updated_date )
VALUES
('CALL', '$media', '$media_2','$fname','$lname', '$street_addr', '$city',
$state','$zip', '$phone_alt', '$phone','$email','$problem','$mc',
'$comments',GetDate() ); ");
The primary key for the table CALLER is an auto-increment. How can I get the Primary Key of the row just inserted after this query ?
Correction: use this.
$query = mssql_query("SELECT ##IDENTITY");
$row = mssql_fetch_assoc($query);
Well if you have any CANDIDATE KEY in the table, you can use that to retrieve the last inserted row.
Say you have a candidate key consisting of columns status, email and problem.
Then you can execute a query like this just after your insert.
$query = "SELECT id FROM CALLER
WHERE
status = '" . $status . "'
AND email = '" . $email . "' AND
problem = '" . $problem . "'";
mssql_query($query);
This will return the id for that entry.
Update
I just saw this in a comment by Mikael to Femi's Answer, you can use SCOPE_IDENTITY()
It returns the las insert id for the current connection in current scope. So it should work for you even if multiple instances do inserts which are interleaved.
So you can simply do this after the insert
$res = mssql_query('SELECT SCOPE_IDENTITY()');
Can anyone show me a query in MySQL that would delete rows from all available columns.
I use this to insert rows:
$sql = "INSERT INTO " . KEYS . " // KEYS is a constant
(key, user_id, time, approved)
VALUES ('" . $randkey . "', '" . $user_id . "', '" . $time . "', '0')";
I need the opposite of this now, delete created rows.
delete from <table> where ....
Keep in mind that the delete statement is always for an entire row.
Using similar syntax sql = "DELETE FROM " . KEYS . " WHERE 1=1";
Replace 1=1 with the conditions for the row you want to delete or it will delete all rows.
Also, it's good to get out of the habit of just dropping variables into SQL as soon as possible, because it will open your code up to SQL Injection attacks. Look into using parameterized queries.