2010-02-20 4 views
16

PHP에서 mysqli와 함께 준비된 문장을 사용하는 법을 배우고 있는데, 보통 쿼리에 문제가있을 경우 첫 번째 단계로 보이는 것을 화면에 표시합니다.준비된 진술의 내용을 보려면 어떻게해야합니까?

준비된 진술로 어떻게 할 수 있습니까?

변수가 대체 된 후 SQL 문을보고 싶습니다.

답변

16

사용하여 준비된 문 : 당신이 문을 준비 할 때이 변수 +가 문을 실행 바인딩 할 때

  • , 그것은 MySQL 서버
  • 로 전송됩니다 만 변수는 MySQL 서버
  • 로 전송됩니다
  • 그리고 statement + bound 변수는 MySQL 서버에서 실행됩니다 - 명령문이 실행될 때마다 "준비"를 다시하지 않고 (이는 동일한 명령문이 여러 번 실행될 때 준비된 명령문이 성능에 좋을 수있는 이유입니다 번)

PHP쪽에 SQL 쿼리의 "빌드"가 없으므로 실제로 해당 쿼리를 가져올 방법이 없습니다.

즉, SQL 쿼리를 보려면, 잘, SQL 쿼리 및 준비된 문을 사용해야합니다.

+0

그게 좀 성가신 = \ 당신은 거기에 실행 된 진술을 가져올 수있는 방법이있을 거라고 생각 – Stomped

+0

당신은 PHP 쪽에서, 주로 디버깅 이유로, 나는 당신이 "SQL을"다시 만들 수 있다고 가정합니다 명령문 실행과 동일한 쿼리 : 변수의 값으로 자리 표시자를 바꾸어야합니다. * (데이터를 이스케이프 처리하는 것은 물론 사용자에게 맡깁니다.) * ;;; 이 작업이 자주 필요한 경우이 작업을 수행하는 함수를 작성할 수 있어야합니다. 그렇지 않다면,'var_dump'는 이미 MySQL 서버에 어떤 데이터가 보내지는지를 보여줄 것입니다. –

+1

@stomped 요점은 실행 된 명령문이 없다는 것입니다. 그 단계는 완전히 건너 뜁니다. – troelskn

0

파스칼 마틴 (+1)과 동의하므로 디버깅을위한 또 다른 기법을 제안합니다 : var_dump() 또는 구문에 삽입하는 모든 변수를 기록하십시오. 그런 식으로 잘못된 데이터인지 논리적으로 잘못된지 알아낼 수 있어야합니다 SQL.

10
  • 당신은 (경우에 당신이 pdo를 사용하는) 준비된 명령문에 대한 몇 가지 정보를 얻을 수 PDOStatement->debugDumpParams를 사용할 수 있습니다.
  • 준비된 문을 logged in MySQL's general log 다음과 같습니다 mysql_stmt_prepare() 및 mysql_stmt_execute() C API 함수로 실행되는 준비된 명령문에 대한
, 서버가 준비하고 당신이 말할 수 있도록 일반 쿼리 로그에 라인을 실행 기록 진술이 준비되고 실행된다.
[...] 서버가 일반 쿼리 로그에 다음 줄을 씁니다.
SELECT [1] SELECT?
[1] general log 활성 디버깅 목적 그래서 3

선택하고 그 파일을 감시 실행한다.

편집 : 오, 질문에 [mysqli] 태그가 있습니다 ... 완전히 간과했습니다.
문이 실행되지 않으면 (double/tripple) 길을 따라 어떤 오류도 발생하지 않았습니까?

echo "<pre>Debug: start</pre>\n"; 

$mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test'); 
if ($mysqli->connect_error) { 
    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); 
} 

$result = $mysqli->query('CREATE TEMPORARY TABLE foo (id int auto_increment, x int, primary key(id))'); 
if (false=== $result) { 
die('error : '. $mysqli->error); 
} 

$stmt = $mysqli->prepare('INSERT INTO foo (x) VALUES (?)'); 
if (false===$stmt) { 
    die ('prepare() failed: ' . $mysqli->error); 
} 

$result = $stmt->bind_param('i', $x); 
if (false===$result) { 
    die('bind_param() failed'); 
} 

$x = 1; 
$result = $stmt->execute(); 
if (false===$result) { 
    die('execute() failed: '.$stmt->error); 
} 

echo "<pre>Debug: end</pre>\n"; 
2

일반적으로 매개 변수가있는 준비된 sql을 디버깅해야 할 때이 작업을 수행합니다.

의 예 준비하고 실행합니다

$sql = "SELECT VAL1, VAL2 FROM TABLE(?, '?', '?', '?', '?', ?, '?', '?', '?')"; 
$prep = ibase_prepare($sql) or die("Error"); 
$query = ibase_execute($prep, $param1, $param2, .....) or $err = true; 
           ^^^^^^^^^^^^^^^^^^^^^^^ 

그것의 문장의 결과 SQL을 디버깅 할 수있는 쉬운 방법 :

printf(str_replace('?', '%s', $sql), $param1, $param2, ....); 
             ^^^^^^^^^^^^^^^^^^^^^^ 
당신 만 교체, 하나 개의 printf를 할 필요가

? 준비된 SQL 문자열에 % s. printf는 모두를 하나의 문자열로 해석하여 각 매개 변수를 대체 된 % s마다 배치합니다.

0

최근 작곡가 통합, 유닛 테스트를 포함하고 참조로 인수 수용을 처리하기 위해이 프로젝트를 업데이트했습니다 (이 작업은 5.6으로 업데이트해야 함).

:


난 당신이 제공해야하는 잠재적 인 쿼리 문자열의 연주를 볼 수 있도록 기본을 mysqlimysqli_stmt 클래스를 확장하는 클래스의 집합을 만들었습니다 당신은 무엇을 찾고있는

https://github.com/noahheck/E_mysqli 당신을 위해 (에 가까운) 드롭 인 교체 정상적인 사용자 정의 mysqli_stmt 객체를 반환 mysqli 객체 때 prepare() 쿼리 문자열.

INSERT INTO registration SET name = 'John Doe', email = '[email protected]' 

이 확장을 사용하여 몇 가지주의 사항이 있습니다에

$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName); 

$query = "INSERT INTO registration SET name = ?, email = ?"; 

$stmt = $mysqli->prepare($query); 

$stmt->bind_param("ss", $_POST['name'], $_POST['email']); 

$stmt->execute(); 

echo $stmt->fullQuery; 

가 될 것이다 : 당신의 매개 변수를 바인딩 한 후, E_mysqli 당신이 stmt 개체의 새 속성으로 결과 쿼리 문자열을 볼 수 있습니다 (github 프로젝트의 README에 설명되어 있음). 그러나 응용 프로그램의 문제를 해결하거나 절차 중심에서 객체 지향 스타일로 전환하려면 대부분의 사용자에게 수준 높은 도움을 제공해야합니다.

github 프로젝트에서 설명한대로 mysqli 확장자를 사용한 실무 경험이 없으며이 프로젝트는 자매 프로젝트 사용자의 요청에 따라 작성되었으므로 생산에 이것을 사용하여 devs 크게 감사하겠습니다.

면책 조항 - 내가 말했듯이,이 확장을 만들었습니다.

0

Lottip과 같은 도구를 사용할 수 있습니다. 아이디어는 MySQL 프록시와 같은 역할을합니다. MySQL 패킷을 파싱하고, 쿼리를 추출하며, params이므로 준비된 구문을 내용으로 볼 수 있습니다.

+0

Lottip의 개념과 사용법을 여기에서 바꾸어 말하십시오. 링크가 영원히 지속되지 않습니다. – atomSmasher

관련 문제