2011-08-06 4 views
1

업데이트 : 아래를 참조하십시오; 모든 추상화를 제거하고 일반 PHP 스크립트를 만들었지 만 여전히 동일한 오류가 발생합니다. 자세한 내용은 아래의 '다른 업데이트'를 참조하십시오 ...PHP MySQL Prepared Statement 가입 오류

원본 게시물 : 데이터베이스 추상화 계층을 통해 올바르게 구성된 쿼리가 있습니다. 나도 같은 쿼리를 생성하지만, 아래와 같이 WHERE 절의 두 번째 피연산자를 parameterises 준비된 문으로 실행하면 내가 잘못된 결과를 얻을

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN 
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = 5c9_dpd_users.cms_usergroup_id 
ORDER BY username asc 

: 쿼리는 다음과 같다. 나는 진술 문 자체가 정확하고 내가 MySQLi 준비를하고 있다고 확신한다. 명령.이 올바른 순서로 기능합니다. 준비된 문 쿼리는 다음과 같습니다 :

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN 
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc 

이 쿼리에 매개 변수가있는 5c9_dpd_users.cms_usergroup_id을 변환 할 것으로 보인다 단순히 '5'쿼리를 실행하면 SELECT 절에서 바로 열을 검색하지만 모든 결과에 대해 동일한 usergroup_name를 반환하기 때문에 -이 사용자 그룹 이름은 5c9_dpd_usergroups_cms.id5 인 결과의 사용자 그룹 이름과 일치합니다.

동적으로 매개 변수를 바인딩하고 있습니다 (call_user_func_array()). 이 경우 ? 매개 변수를 i으로 바인딩하도록 지정합니다. 나는 아마도 이것을 5c9_dpd_users.cms_usergroup_id5으로 변환했다고 생각했지만 행운을 남기는 세 가지 다른 데이터 유형 (s, bd)을 모두 시도했습니다.

NB : 데이터베이스 추상화 계층을 여러 번 사용해도 문제가 없지만 최근에 개발 된 조인 (join)을 실행 한 첫 번째 인스턴스입니다. 다시 말하면, 쿼리는 매개 변수화되지 않은 경우 PHP 및 MySQL 콘솔을 통해 올바른 결과를 반환하지만 PHP 준비 명령문 함수를 통해 ?이 주어진 경우 위와 같이 결과가 정확하지 않습니다.

누구든지 도움을받을 수 있다면 크게 감사하겠습니다. 나는이 문제에 대한 도움으로 밤새도록 인터넷 검색을 해왔으며 어디서나 비슷한 문서를 찾을 수 없습니다. 고맙습니다.

편집 (PHP 코드 제공) : 쿼리 지금 실행

$stmt->select_prep(array('users.id', 'users.username', 'users.cms_usergroup_id', 'usergroups_cms.usergroup_name', 'users.email'), array('users')); 
$stmt->left_join_prep('usergroups_cms'); 
$stmt->on_prep('usergroups_cms.id', '=', 'users.cms_usergroup_id', 'i'); 

$stmt->order($column, $asc_desc); 
$stmt->execute_prep(); 

을, 내가 할 일은>이 fetch_prep(), 랩핑 방법은 기본적으로 결과를 검색하는 $ stmt- 전화입니다 세트. 이 클라이언트 코드가 생성 한 쿼리는 위에서 예로 든 두 번째 매개 변수화 된 쿼리로 제공되었습니다.

나는 나의 $의 stmt-> execute_prep() 메소드에서 디버깅 코드를 인쇄하고 쿼리에 바인딩됩니다 매개 변수는 다음과 같이 올바르게 나타납니다

Array 
(
    [0] => i 
    [1] => 5c9_dpd_users.cms_usergroup_id 
) 

이 그것을 하나 개의 매개 변수를 바인딩 의미 (키 1)를 int (키 0)로 사용합니다. 나는 또한 문자열, double 및 blob로 바인딩을 시도했지만 아무런 효과가 없습니다.

ANOTHER 업데이트 :

나는 완전히 내 데이터베이스 추상화 계층을 제거하기 위해 테스트 스크립트를 생성하고, 그 결과는 동일합니다 : 더 CMS의 사용자 그룹 이름은 반환되지 않습니다. 여기에 스크립트입니다 :

<?php 
$mysqli = new mysqli('localhost', 'root', '', 'frame'); 

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ? 
ORDER BY username asc"; 

$stmt = $mysqli->prepare($q); 
$stmt->bind_param('i', $param); 
$param = 'ac9_dpd_users.cms_usergroup_id'; 
$stmt->execute(); 

$stmt->bind_result($a, $b, $c, $d, $e); 

while ($stmt->fetch()) { 
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>"; 
} 

$stmt->close(); 
unset($mysqli); 
?> 

출력 :

id: 7 
un: ADD 
id: 1 
cms name: 
email: [email protected] 

id: 1 
un: New User 
id: 2 
cms name: 
email: [email protected] 

+0

http://www.php.net/manual/en/mysqli-stmt.bind-param.ph 당신의 실행 후 쿼리 p call_user_func_array()를 명령문에 바인딩 매개 변수와 함께 사용하는 것에 대한 경고가 있습니다. 이것이 당신에게 영향을 줄 수 있다고 생각합니까? – Pelshoff

+0

비표준 매개 변수를 전달하면 치명적/경고 오류가 발생하므로 (필자는 정확히 어떤 것을 잊어 버렸기 때문에) 그렇게 생각하지 않습니다. – Pete171

+0

매개 변수를 바인딩하는 데 사용하는 코드 중 일부를 표시 할 수 있습니까? 누가 알면, 거기에 뭔가를 놓친 것일 수도 있습니다. – Pelshoff

답변

1

어쩌면 내가있어 조금 까다로운하지만 난 숫자로 테이블/필드 이름을 시작할 것 . 문자를 사용하거나이 괴상한 이름을 뒷받침으로 사용하십시오 (`). 그것은 작동해야합니다.

PHP 매뉴얼에 보도 된 바와 같이
 ... 
    ON ac9_dpd_usergroups_cms.id = ? 
    ... 
    $stmt->bind_param('i', $param); 
    $param = 'ac9_dpd_users.cms_usergroup_id'; 

, mysqli::prepare이 where 절과에 매개 변수를 사용할 수

편집 나에게 경고 편집 된 스크립트 소리의

일부 지점 (질문의 변화에 ​​따라) 은 쿼리의 열 이름을 변경할 수 없습니다.

는 또한 준비된 쿼리에 삽입하기 전에 숫자로 값을 변환해야하는 문자열의 정수 바인드를 수행하고 $의 PARAMS 함께 무슨 일이 일어나고 있는지 확인하기 위해 0

을 발행 sqlstate 문으로 변환해야

... 
$stmt->execute(); 
$sqlError = $stmt->sqlstate(); 
if($sqlError != '00000') die($sqlError); 
... 

가능한 솔루션 :

<?php 
$mysqli = new mysqli('localhost', 'root', '', 'frame'); 

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ac9_dpd_users.cms_usergroup_id 
ORDER BY username asc"; 

$stmt = $mysqli->prepare($q); 
$stmt->execute(); 

$stmt->bind_result($a, $b, $c, $d, $e); 

while ($stmt->fetch()) { 
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>"; 
} 

$stmt->close(); 
unset($mysqli); 
?> 
+0

테이블 이름의 이름이 바뀌었고 (그에 따라 변경된 쿼리) 이제는 사용자 그룹 이름이 검색되지 않습니다 ... – Pete171

+0

나는 위의 자신을 여러 번 재현했지만 확실하지 않았습니다 자리 표시자가 작동하지 않는 이유; 쿼리의 열 이름을 변경할 수 없다는 것을 알고 있으면 내 시도가 예기치 않은 결과를 산출하는 이유를 분명히 설명합니다! 이 문제를 DB 추상화 레이어와 관련하여 해결하기 위해 매개 변수가 자리 표시 될지 여부를 나타내는 WHERE 절과 ON 절에 클라이언트 코드가 제공해야하는 다른 매개 변수를 추가했습니다. 설명해 주셔서 감사합니다. – Pete171

관련 문제