So basically what I am trying to do is when a user of my site creates a new account on our register page, I'd like the primary key from the newly created row on the User table (basic info table, email, password, etc.) to be inserted into a new row on the Profile table (more descriptive info, about me, display name, etc.)
I'd like to do this in PHP and any help would be appreciated.
if you are using mysqli look at:
http://www.php.net/manual/en/mysqli.insert-id.php
Get the id after your first insert and then use this in your next insert.
If doing it "in php" isn't really a requirement, then you can use MySQL's built in Trigger mechanism to do this update.
Triggers cause something to happen AFTER or BEFORE an event(INSERT, UPDATE,DELETE)
So your trigger would be:
CREATE TRIGGER thistrigger AFTER INSERT
ON User FOR EACH ROW
UPDATE PROFILE SET "whatever"
On Triggers: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
I think there isn't a really elegant way in MySQL, basically because INSERT doesn't return anything. PostgreSQL does allow for an INSERT ... RETURNING clause, but that's an extension.
That said, if you're using the mysql_* functions in PHP, you can use mysql_insert_id, which might suffice for your needs (i.e. if your primary key is an AUTO INCREMENT integer).
If you are using a mysql database, you could alternatively do another query call from php with the following query:
"SELECT LAST_INSERT_ID();"
More info about it here: http://www.jpgtutorials.com/mysql-last_insert_id-function
It is connection specific. Concurrent inserts from different connections won't affect the current connection.
Related
I have this two tables:
I also have a dynamic form in which it contains table and the user can add rows and the data from it will be inserted in tblcamealsformdetails but the basis for inserting it is the id from tblcamealsform. How do I insert all the values to the two tables simultaneously?
Here's my form:
You will enter data first in table tblcamealsform. You insert ID from that query.
That ID you will use then to insert the rest of the data, along with the insert ID, in table tblcamealsformdetails.
So you don't do it simultaniously. You add the dependencies first.
To get the insert-id from the last query you executed, you will need mysql_insert_id().
See http://php.net/manual/en/function.mysql-insert-id.php
In answer to the comment what will happen if multiple users use the form at the same time:
Since you open a mysql connection at the top of your script which will result a unique connection pointer and all of the mysql-functions you call automatically reference to that pointer I think mysql_insert_id() will always reference to the latest query performed by the current connection. So another thread by another user would not interfere with this.
Please note that I am not 100% sure about this though.
Anyway: I am using this for about 10 years now some of which include high-traffic websites and I have never experienced any problems using this method, so in my opinion you can safely use it.
There is one exception to this:
You must always call mysql_insert_id() immediately after executing the query you want the ID for. If you execute any other query in the meantime (for example, you call a method of another object which performs an insert-query) mysql_insert_id() will return the ID of that query instead.
This is mistake I have made in the past and which you have to be aware of.
I'd like to point you using LAST_INSERT_ID:
when doing multiple-row inserts, LAST_INSERT_ID() will return the value of the first row inserted (not the last).
When a few users try to insert a row into the table, this error appears:
(325 is the ID of the row. there is no auto increasment because I'm doing it myself because I need it.)
I remember that in asp they have the lock() method that actually prevents this kind of errors.
Is there something similiar in PHP?
Code will be added if asked although I dont think its required.
Thank you very much!
Now you see why you shouldn't assign IDs manually :)
Change your table to start assigning IDs automatically:
ALTER TABLE your_table AUTO_INCREMENT=last_assigned_id+1
If you insist on implementing a lock, you can use sem_acquire
I have a PHP script that creates an entry into a mysql database. The PHP inserts all of the data except the primary key, which mysql automatically increments. The problem is that i want to insert information into two tables, and these tables must be able to associate. Is there a way to have PHP create an entry in one table in mysql, then figure out the incremental primary key value from that first table, in order for it to insert into the second mysql table as a reference?
Yes. This is certainly doable. The function/method you use to get the auto-incremented value that was just inserted will depend on the way you access MySQL from PHP. If you're using the mysql_ functions, use mysql_insert_id(). If you're using the mysqli_ functions (or OO versions), use mysqli_insert_id(). If you're using PDO, use PDO::lastInsertId(). In all cases, the function delegates to the MySQL function last_insert_id() which is local to the connection so you need not worry about concurrent threads interfering with each other.
You can use:
mysql_insert_id()
This will return the id of the previous query. See below:
http://php.net/manual/en/function.mysql-insert-id.php
To get the unique ID inserted for the first table you can use LAST_INSERT_ID() and save that as reference for your second table:
SELECT LAST_INSERT_ID();
Use this as another option I suppose. For PHP you can use mysql_insert_id as suggested :)
This seems to be a simple problem, but after a while of searching I can't figure out the answer.
I currently have a MySQL table in my local database used by a webapp, and them same table on a database in a remote server. Right now, I'm using the CREATE TABLE IF NOT EXISTS command through PHP to create the table on the databases:
CREATE TABLE IF NOT EXISTS users (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(18) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
However, let's say I make a modification to the local database, adding a collumn, for example. It would be really annoying to have to go and change the remote database every time I change the local one. Is there an easier way to run code to create a table if it doesn't exist, and if it does exist, make sure it's structure matches that of the create table structure?
Here's an example, to make what I'm trying to convey a little clearer. Let's say on the local database I have a users table, and I decide that in my webapp I want to have another collumn, password. So I go to the local database and add a password collumn. Is there PHP/MySQL code I can run to check if the users table exists, and if it does, make sure it has a password collumn, and if not, add it?
What you are actually looking for are Migrations, e.g. you are looking for a Schema Management Tool that lets you manage your Database structure in versioned code diffs.
For instance, for your described scenario you would first create a script to create the table, e.g. 001_create_user_table.sql. Then you'd use the schema manager to connect and deploy these changes to your databases.
When you want to change or add something, you just write another script, for instance, 002_Add_Password_Column_To_User_Table.sql. Fill in just the code to do that change. Then run the schema manager again.
Typically, you tell the Schema Manager to go through all existing migrations files. On each run, the Schema manager will update a changelog table in the database, so when you run it, it will know which of your scripts it should apply.
The good thing is, you can add these migrations to your regular VCS, so you will always know which database schema you had at which version of your application. And you will have a proper changelog for them.
To directly answer your question you can create temporary procedures to detect field existence like using a query like this:
SHOW COLUMNS FROM table_name LIKE 'column_name';
However in the real world, database changes are general rolled into three scripts. A create script and two deltas one up and one down. Then the database is versioned so that you know at what state the database is in at any given time.
To specifically check for a password column you can use DESCRIBE:
$colExists = false;
$res = mysql_query('DESCRIBE `users`');
while ($row = mysql_fetch_assoc($res)) {
if ($row['Field'] == 'password') {
$colExists = true;
break;
}
}
if (!$colExists) {
// create column
}
However, you should check into replication or some other automated tool to see if they would be a better solution for you.
Follow these steps (you can easily implement this in PHP, I assumed that the name of the table is Foo)
1.) Run the following code:
desc Foo
2.) Based on the result of the first step you can make your create table command (and you should)
3.) Store your data from the existing table which will be replaced in a variable (Optional, you only need this if you can potentially use data from the old table)
4.) Modify the extracted rows from step 3.) so they will be compatible with your new definition (Optional, you only need this if you can potentially use data from the old table)
5.) Get the rows from your new Foo table
6.) Merge the results got in steps 4.) an 5.) (Optional, you only need this if you can potentially use data from the old table)
7.) Run a drop table for the old table
8.) Generate a replace into command to insert all your rows into the newly created Foo table (you can read more about this here)
After these steps, as a result, you will have the new version of the table. If your tables are too large, you can do a CREATE TABLE IF NOT EXISTS command and if that was not successful, run the alter command.
Also, you can make a library to do these steps and will use that in the future instead of solving the same problem several times.
EDIT:
You can connect the database using this function: mysql-connect (documentation here)
You can run a query using this function: mysql-query (documentation here)
Based on the first step you will get the field names (let's assume you store it in a variable called $bar) and you can use your result to generate your select command (connecting to the database where you have important data. It may be both):
$field_list = "1";
foreach ($bar as $key => $value)
$field_list.= ",".$bar[$key];
mysql_connect(/*connection data*/);
mysql_query("select ".$field_list." from Foo");
You can use your new resource to build up an insert command to insert all your important data after deletion recreation (about resources read more here, about how you can generate your insert you can read here, but I suggest that you should use replace into instead of insert which works like the insert, except that it replaces the row if it already exists, it's better here than an insert, read more here)
So, use mysql_connect and mysql_query, and the resource returned by the mysql_query function can be used for replace into later (I've linked now the URL's for everything you need, so I'm pretty sure you'll solve the problem.), apologies for being not specific enough before.
I am familiar with the MySQL function LAST_INSERT_ID; is there a similar function for performing the same query with a MS Access database via ODBC?
In my specific case, I am using PHP+PDO to insert rows into an Access database, and would like to know the last primary key value of each insert as they are performed.
If this functionality is not available, are there any alternatives? (without changing the database)
Thank you.
It seems that Access 2000 or later supports the ##IDENTITY property. So, you would only need to select its value after an INSERT:
select ##IDENTITY from myTable
Please see the MSDN link: Retrieving Identity or Autonumber Values
In short:
[...] Microsoft Access 2000 or later does support the ##IDENTITY property to retrieve the value of an Autonumber field after an INSERT. Using the RowUpdated event, you can determine if an INSERT has occurred, retrieve the latest ##IDENTITY value, and place that in the identity column of the local table in the DataSet.
As others have said, SELECT ##IDENTITY works with Jet 4 and the ACE.
A new consideration has been introduced with Access 2010, and that's because the new ACE version supports table-level data macros, which are the equivalent of triggers. Thus, an insert in one table might trigger an insert in another, so that ##IDENTITY might be the value for the second table instead of the top-level one. So far as I know, there is no equivalent to SQL Server's SCOPE_IDENTITY() for this scenario.
I have asked about it in other Access forums and nobody seems to know. It's something to watch for should you be using an ACCDB with table-level data macros.
I've never attempted to use access with php, but two ideas come to mind, The first one is simple. And that's to simple select max(id) from table after your insert, since it is auto incrementing you will get the highest value which should be the insertted value. Secondly you can try using odbc_cursor (http://au2.php.net/manual/en/function.odbc-cursor.php).
Try running "SELECT ##IDENTITY FROM MyTable" after your insert.