2017-11-16 3 views
0

나는 모든 삽입 쿼리가 제대로 작동하면 어떻게 보장 할 수있는 시나리오가 있습니다. 백엔드 코딩을 위해 PHP를 사용하고 데이터베이스에 mysql을 사용하고 있습니다. 아래에서 나는 나의 문제를 간략하게 설명하고있다.관계형 mysql 데이터베이스의 다중 테이블에서 다중 삽입 쿼리를 수행하는 적절한 방법은 무엇입니까?

두 개의 테이블이 있습니다. 한 테이블은 login_details 용이고 다른 테이블은 personal_details 용입니다. 내 테이블 구조가 여기에 있습니다.

표 login_details 여기 USER_ID는 고유의 기본 키와 sl_num은 자동 증분 :

th{ 
 
    padding: 3px; 
 
    border: 1px solid black; 
 
} 
 

 
td{ 
 
    padding: 3px; 
 
    border: 1px solid black; 
 
}
<table> 
 
    <thead> 
 
     <th>sl_num</th> 
 
     <th>user_id</th> 
 
     <th>email</th> 
 
     <th>password</th> 
 
    </thead> 
 
    <tbody> 
 
     <tr> 
 
     <td>1</td> 
 
     <td>123</td> 
 
     <td>[email protected]</td> 
 
     <td>5567</td> 
 
     </tr> 
 
     <tr> 
 
     <td>2</td> 
 
     <td>246</td> 
 
     <td>[email protected]</td> 
 
     <td>9908</td> 
 
     </tr> 
 
    </tbody> 
 
</table> 
 

내 두 번째 테이블 personal_details입니다. 나는이 테이블에 값을 삽입하기 위해이 코드를 사용

th{ 
 
    padding: 3px; 
 
    border: 1px solid black; 
 
} 
 

 
td{ 
 
    padding: 3px; 
 
    border: 1px solid black; 
 
}
<table> 
 
    <thead> 
 
     <th>sl_num</th> 
 
     <th>user_id</th> 
 
     <th>name</th> 
 
     <th>address</th> 
 
     <th>age</th> 
 
    </thead> 
 
    <tbody> 
 
     <tr> 
 
     <td>1</td> 
 
     <td>123</td> 
 
     <td>Daniel</td> 
 
     <td>San Francisco</td> 
 
     <td>23</td> 
 
     </tr> 
 
     <tr> 
 
     <td>2</td> 
 
     <td>246</td> 
 
     <td>Lucy</td> 
 
     <td>London</td> 
 
     <td>27</td> 
 
     </tr> 
 
    </tbody> 
 
</table>

을 그리고 다음은 또한 USER_ID는 기본 키이고이 키는 두 개의 테이블과 sl_num 사이의 관계를 유지하는 자동 증분입니다.

<?php 
    $user_id = uniqid(); 
    $email = $_POST['email']; 
    $password = $_POST['password']; 
    $name = $_POST['name']; 
    $address = $_POST['address']; 
    $age = $_POST['age']; 

    $con = mysqli_connect('localhost', 'username', 'password', 
         'user_db'); 

    $query = "INSERT INTO `login_details` (`user_id`, `email`, 
      `password`) VALUES ('$user_id', '$email', '$password')"; 
    mysqli_query($con,$query); 

    $query2 = "INSERT INTO `personal_details` (`user_id`, `name`, 
      `address`, `age`) VALUES ('$user_id', '$name', '$address', 
      '$age')"; 
    mysqli_query($con,$query); 

    echo 'User created successfully';?> 

하지만 유선 문제는 한 번 발생했습니다. 세 번째 사용자 이름 'John Doe'이 (가) 자신의 계정을 만들려고합니다. personal_details 테이블의 세부 사항이 성공적으로 삽입되었지만 login_details의 세부 사항이 삽입되지 않은 이유가 있습니다. 따라서 사용자 'John Doe'는 테이블에 개인 정보가 있지만 로그인 정보가 없으므로 로그인 할 수 없습니다.

그래서 이러한 종류의 멀티 삽입 상황에 대한 최선의 해결책은 무엇입니까? 이 상황을 어떻게 막을 수 있습니까? 즉, 한 행이 login_details에 삽입되면 시스템은 상대 행이 personal_details 테이블에도 삽입되도록해야합니다. 두 개가 성공적으로 삽입되면 트랜잭션이 발생하거나 한 행이 삽입되고 다른 행이 삽입되지 않으면 시스템은 자동으로 삽입 된 행을 삭제하고 실패 메시지를 표시합니다.

+1

나는 거래에 대해 배우는 것이 좋습니다. – AndySavage

+0

PHP 오류 로그에서 *를 지우셨습니까? 또한'SHOW CREATE TABLE '을 실행하면 내부 구조를 볼 수 있습니다. 기본 키와 외래 키를 결합하는 것처럼 보입니다. * user_id는 기본 키이며이 키는 두 테이블 간의 관계도 유지합니다 *. 마지막으로, 왜 MySQL에서는 자동 번호를 만들지 만 PHP에서는'uniqid()'를 만들까요? – Parfait

+0

트랜잭션은 이것이 핵심입니다. – Strawberry

답변

0

쿼리가 실패한 이유는 아마도 SQL 컨텍스트의 변수를 이스케이프 처리하지 않기 때문일 수 있습니다. 즉, 문자열 중 하나에 '이 있으면 SQL 문이 유효하지 않게됩니다. 이것은 known as an SQL injection attack이며 애플리케이션을 신속하게 공격에 취약하게 만들 수 있습니다.

이러한 공격을 완화하는 일반적인 방법은 use a prepared statement instead입니다.

이렇게하면 첫 번째 쿼리가 실패 할 경우 두 번째 쿼리를 취소 할 수 있습니다. 하지만 두 번째 오류가 발생하면 어떻게해야합니까? (어떤 이유로 올바른 사용을했을 때 ... 은 실제로이 아니며 변수를 올바르게 이스케이프 처리했지만 디스크가 가득 차있을 수는 없습니다.).

SQL 트랜잭션에서 두 문을 모두 래핑 한 다음 쿼리가 실패 할 경우 트랜잭션을 커밋하거나 롤백 할 수 있습니다. MySQL의 테이블/데이터베이스 유형이 트랜잭션을 지원하고 자동 커밋이 사용되지 않는다고 가정합니다.

mysqli_begin_transaction($con)으로 전화하여 mysqli를 사용하여 트랜잭션을 시작할 수 있습니다.

그런 다음 mysqli_commit 또는 mysqli_rollback을 호출하여 트랜잭션을 커밋하거나 롤백 할 수 있습니다.

이전 문이 실패했는지 확인하려면 mysqli_error으로 전화하십시오.

+0

제안 해 주신 MatsLindh에게 감사드립니다. 나는 이것이 내 문제를 해결할 것이라고 생각한다. – SAAN07

관련 문제