2014-09-19 2 views
2

У меня есть 3 таблицы: пользователя, студент, studentdetails первичного ключмножественной вставки в одной транзакции Mysqli php5

пользователя является внешним ключом для поля в таблице студента (идент) и первичном ключ студента является внешним ключом для поле в таблице studentdetails (studentid).

мне нужно вставить данные из одной формы для всех 3-х таблиц в одном представить следующее сценарий SQL:

$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); 

    "; 

Я не могу понять эту проблему, выше скрипт работает в MySQL (phpmyadmin), но в php это не работает. Я понимаю, мне нужно использовать multi_query (??), который я есть, но он не дает никаких ошибок и вставок в две таблицы, но не в третьем. Я чувствую, что это может быть связано с выражением SELECT между ними? В конце концов, я был бы очень признателен за любую помощь. Спасибо за кучи заранее.

+1

Попытка выполнить несколько операторов SQL не является хорошей идеей. Разделите операторы на несколько вставок и выполните их отдельно. – GordonM

+0

Я бы сделал отдельные инструкции SQL, чтобы иметь возможность управления и обработки ошибок. Но если вы считаете, что вам нужно сделать всю эту работу базы данных одним выстрелом, создайте хранимую процедуру, которая сделает все это. –

ответ

1

Похоже, вы пытаетесь запустить несколько операторов SQL, разделенных точкой с запятой из mysqli. Это не работает. Вам нужно выдать каждое отдельное заявление отдельно.

Вы можете использовать транзакции MySQL (если вы используете InnoDB или какой-либо другой метод доступа для своих таблиц, а не MyISAM: MyISAM не обрабатывает транзакции).

Вы бы сделать это следующим образом:

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

Это заставит все вставки и т.д., становятся видимыми одновременно.

НО: вы пытаетесь использовать самые последние идентификационные номера автоинкремента. Вы делаете это неправильно. Вы должны использовать LAST_INSERT_ID() функцию MySQL в месте вашего шаблона

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

. Это работает, потому что LAST_INSERT_ID() поставляет значение идентификатора из вашей первой вставки, поэтому вторая вставка будет использовать его. Это безопасно, даже если несколько программ вставляют вещи в таблицу, потому что MySQL сохраняет отдельное значение для каждого соединения с программой. Это быстрее, чем у вас, потому что ему не нужно смотреть на таблицу и возвращать значение вашей программе перед ее использованием.

Так сделайте это, и вы получите то, что хотите.

/* 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); 
+0

спасибо. Я использую InnoDB, и я использовал last_insert_ID(), но где-то читал, что он может не всегда работать, однако я изменил его сейчас. Кроме того, как предложил Гордан и Эд, могу я спросить, если его плохая идея использовать multi_query? Я могу изменить код, чтобы каждый раз отправлять один sql, но подумал, что лучше позволить mysql выполнить работу за один раз и отправить подтверждение на php? Цените свою помощь, спасибо еще раз! – Anx

+1

'LAST_INSERT_ID()' очень надежен, пока вы не редактируете свой код, чтобы проскальзывать больше инструкций 'INSERT' между ними, зависящими от него. Вы можете использовать 'multi_query', если хотите. Но в этом API нет обработанного транзакционного контроля. –

Смежные вопросы