2014-12-16 2 views
1

자동차 테이블에 레코드를 삽입하려고합니다. 다음은 테이블의 축소 된 버전입니다.PDO가 빈 값을 null로 처리하는 이유는 무엇입니까?

참고 : 실제 작업 모델이 아니므로이 모델을 사용하거나 평가해서는 안됩니다. 나는 단순화 된 방식으로 문제를 보여주고있다.

mysql> describe desc_autos; 
+-----------------+------------------+------+-----+---------------------+----------------+ 
| Field   | Type    | Null | Key | Default    | Extra   | 
+-----------------+------------------+------+-----+---------------------+----------------+ 
| car_id   | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| automobile_name | varchar(25)  | NO | MUL |      |    | 
+-----------------+------------------+------+-----+---------------------+----------------+ 
7 rows in set (0.00 sec) 

mysql> select count(*) FROM desc_autos WHERE automobile_name IS NULL; 
+----------+ 
| count(*) | 
+----------+ 
|  0 | 
+----------+ 
1 row in set (0.00 sec) 

mysql> select count(*) FROM desc_autos WHERE automobile_name = ''; 
+----------+ 
| count(*) | 
+----------+ 
| 19322 | 
+----------+ 
1 row in set (0.02 sec) 

+-------------+ 
CREATE TABLE `desc_autos` (
    `car_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `automobile_name` varchar(15) NOT NULL, 
    PRIMARY KEY (`car_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 | 
+-------------+ 
1 row in set (0.00 sec) 

그래서 당신은 automobile_name 필드가 NOT NULL입니다보고, 빈 값은 많은 레코드를 표시하고있다. (필드 이름을 무시하십시오. null이 아닌 값이있는 필드가 허용됩니다.)

원시 MySQL 함수에서 PDO로 변환 중입니다. 비어있는 automobile_name 값을 가진 레코드를 삽입하면 문제가 없습니다. 정상적으로 작동합니다. automobile_name이 비어 있으면 PDO가 작동하지 않습니다.

$automobile_name = ''; 
    try 
    { 
     $q = " 
      INSERT INTO 
       desc_autos 
       (
        automobile_name 
       ) 
      VALUES 
       (
        :automobile_name 
       ) 
     "; 
     $stmt = $dbx_pdo->prepare($q); 
     $stmt->bindParam(':automobile_name', $automobile_name, PDO::PARAM_STR); 
     $stmt->execute(); 
     return true; 
    } catch(PDOException $err) { 
     log_error(); 
     return false; 
    }  
} 

이 다음과 같은 오류가 발생합니다

Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'automobile_name' cannot be null 

은 내가 암시 적으로 NULL 값을 삽입하는 PDO를 말할 줄 알았는데, 그렇지 않으면 빈 값이 같은 ... 빈 값을 삽입 할 것입니다.

예 :

$stmt->bindValue(':automobile_name', !empty($automobile_name) ? $automobile_name : NULL, PDO::PARAM_STR);

나는이 경우 NULL을 삽입 할 필요가 아니에요 - 나는 주어진 필드에 빈, null이 아닌 값을 삭제해야합니다.

질문 :

왜 PDO가 null로 빈 값을 치료한다?

+0

mysql_query()로 작업 한'IS NULL'을 암시하고 있습니까? PDO가 실제로 MySQL 표현식에 영향을주지 않기 때문입니다.삽입하는 경우, NULL 값을 빈 문자열로 변환하는'PDO :: PARAM_STR'을 사용하여 값을 바인딩합니다. – mario

+0

@mario 나의 반응 역시 그렇지만 맨 위에는'$ automobile_name = '';이 변수가 명시 적으로 빈 문자열로 설정되어 있습니다. –

+0

@mario 이전에이 삽입 쿼리는'$ q = "INSERT INTO desc_autos (automobile_name) VALUES ($ automobile_name)";와 같이 mysqli_query ($ dbx, $ q); 공백 (또는 null)이라도, MySQL에서는 공백 값으로 삽입됩니다. –

답변

4

빈 문자열을 NULL으로 변환하지 않도록 ATTR_ORACLE_NULLS (이름을 모르겠 음)을 적절한 설정으로 설정해야하는 것처럼 들립니다. 분명히 현재 값은 PDO::NULL_EMPTY_STRING이며 빈 문자열 ''이 NULL이됩니다.

// Set it to "natural" mode so NULLs and empty strings aren't modified 
$dbx_pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL); 

문서 : PDO connection attributes

참고 : 내 빠른 테스트에 따르면, PDO::NULL_NATURAL 기본 설정으로 나타납니다, 그러나 아마 당신은 다른 곳에서 수정되었습니다.

SHOW CREATE TABLE 출력을 기준으로 automobile_name 열은 NOT NULL이지만 명시 적으로 기본값이 정의되어 있지 않습니다. 나는 빈 문자열 ''으로 기본값을 설정하고 PDO가 NULL을 삽입하도록 허용하는 방법을 택할 것입니다. 마리오 메인 코멘트 스레드에서 언급 된 바와 같이 :

ALTER TABLE desc_autos MODIFY `automobile_name` varchar(15) NOT NULL DEFAULT ''; 

을 PDOStatement bindParam()에서, 당신은 그 기본을 사용하여 데이터베이스를 강제로 PHP null 또는 빈 문자열 '' 중 하나를 사용할 수 있습니다. 현재 라인을 변경하지 않아도됩니다 :

$stmt->bindParam(':automobile_name', $automobile_name, PDO::PARAM_STR); 
+0

왜 그런 이름을 붙일 수있을 지 모르겠지만 oracle db에서는 NULL == ''을 확인할 수 있습니다. 다른 데이터베이스에 익숙해지면 귀찮아합니다. –

+0

방금 ​​시도해 본 결과 오류가 계속 발생합니다. 이전에 사용했던 질문에 대한 내 의견을 참조하십시오. @mario별로 표 구성표를 수정해야하는 것 같습니다. –

+0

@acoder 에뮬레이트 된 준비 또는 실제 준비를 사용하고 있습니까? 에뮬레이션을 사용하면이 attr을 수정하여 빈 문자열로 변환하기 위해 NULL을 얻을 수 있지만 다른 방법은 필요 없습니다. 진짜, 모방되지 않은 준비로 나는 변화를 가져올 수 없습니다. 그러나 테이블을 보면 이미 디폴트 값으로'' '를 사용하고있는 것처럼 보입니다. 'SHOW CREATE TABLE desc_autos'를 게시 할 수 있습니까? –

관련 문제