Anx
Anx

Reputation: 141

Multiple Insert in one transaction mysqli php5

I have 3 tables: user, student, studentdetails

User's primary key is the foreign key for a field in table student (userid) and student's primary key is foreign key for a field in table studentdetails (studentid).

I need to insert data from one form to all 3 tables in one submit, following is the SQL script:

    $sql = "

    INSERT INTO `tbluser`(`username`, `password`, `roleid`, `datecreated`)
    VALUES ('$email','$password', '$role', CURRENT_TIMESTAMP);

    SELECT @uid := MAX(`userid`) FROM `tbluser`;

    INSERT INTO `tblstudent` (`userid`, `scholarnumber`, `firstname`, `middlename`,
    `lastname`, `datecreated`)
    VALUES ('@uid', '$scholar_no', '$first_name', '$middle_name', '$last_name',
    CURRENT_TIMESTAMP);


    SELECT @stuID :=  MAX(`studentid`) FROM `tblstudent`;

    INSERT INTO `tblstudentdetails` (`studentid`,`dob`, `studenttype`, `gender`,
    `religion`, `category`, `currentsuburbid`,   `currentcityid`, `currentaddress1`,
    `currentzipcode`, `currentstateid`,  `currentcountryid`,`mobile`,`phone1`,`email1`,
    `passportnum`, `permasuburbid`,  `permaaddress1`, `dateofjoining`,
    `admissionreferenceof`, `datecreated`, `dateupdated`) 

    VALUES ('@stuid', '$dob' ,'$studenttype' ,'$gender','$religion','$category',
    '$currentsuburbid', ' $currentcityid', '$currentaddress1', '$currentzipcode',
    '$currentstateid', '$currentcountryid', '$mobile',
    '$phone1','$email1','$passportnum','$permanentsuburbid', '$permanentaddress1',
    '$doj', ' $admissionreference',current_timestamp, current_timestamp);

    ";

I am not able to figure out the problem, the above script works in mysql (phpmyadmin) but in php it doesn't work. I understand, I need to use multi_query (??) which I am but it doesn't give any error and inserts in two tables, but doesn't in the third one. I feel it might be to do with the SELECT statement in between? At wits end here, I would greatly appreciate any help. Thanks heaps in advance.

Upvotes: 2

Views: 1647

Answers (1)

O. Jones
O. Jones

Reputation: 108641

It looks like you're trying to run multiple SQL statements separated by semicolons from mysqli. That doesn't work. You need to issue each distinct statement separately.

You can use MySQL's transactions (as long as you're using InnoDB or some other access method for your tables, and not MyISAM: MyISAM doesn't handle transactions).

You'd do that as follows:

$connection->begin_transaction();
/* issue your statements one by one */
$connection->commit();

This will cause all your inserts, etc, to become visible simultaneously.

BUT: you're trying to make use of your most recent autoincrement ID numbers. You're doing this wrong. You need to use MySQL's LAST_INSERT_ID() function in place of your

SELECT @uid := MAX(`userid`) FROM `tbluser`;   /*wrong*/

pattern. This works because LAST_INSERT_ID() delivers the value of the ID from your first insert, so the second insert will use it. It's safe even if multiple programs are inserting things to the table because MySQL keeps a separate value for each program connection. It's faster than what you have because it doesn't have to look at the table, and return the value to your program before using it.

So do this and you'll get what you want.

/* do the first insert, using an autoincrementing uid column */
INSERT INTO `tbluser`(whatever, whatever, whatever)
              VALUES (whatever, whatever, whatever);
/* now LAST_INSERT_ID() contains the value inserted into tbluser.uid */

/* do the second insert, using the id from the first insert into tblstudent.userid */
INSERT INTO `tblstudent` (`userid`,         whatever, whatever, whatever)
                  VALUES (LAST_INSERT_ID(), whatever, whatever, whatever);
/* now LAST_INSERT_ID() contains the value inserted into tblstudend.studentid */

/* use that value to insert into tblstudentdetails.studentid */
INSERT INTO `tblstudentdetails` (`studentid`,      whatever, whatever, whatever) 
                         VALUES (LAST_INSERT_ID(), whatever, whatever, whatever);

Upvotes: 1

Related Questions