동기화되지 않은 명령 지금이 명령을 실행할 수 없습니다.


93

mysqli를 통해 두 개의 MySQL 쿼리를 호출하는 PHP 코드를 실행하고 "명령이 동기화되지 않았습니다. 지금이 명령을 실행할 수 없습니다."라는 오류 메시지가 표시됩니다.

내가 사용하는 코드는 다음과 같습니다.

<?php
$con = mysqli_connect("localhost", "user", "password", "db");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s\n". Mysqli_connect_error();
    exit;
}
$con->query("SET NAMES 'utf8'");
$brand ="o";
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE % ? %";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s", $brand);
    $numRecords->execute();
    $data = $con->query($countQuery) or die(print_r($con->error));
    $rowcount = $data->num_rows;
    $rows = getRowsByArticleSearch("test", "Auctions", " ");
    $last = ceil($rowcount/$page_rows);
}  else {

print_r($con->error);
}
foreach ($rows as $row) {
    $pk = $row['ARTICLE_NO'];
    echo '<tr>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="deleterec(\'Layer2\', \'' . $pk . '\')">DELETE RECORD</a></td>' . "\n";
    echo '</tr>' . "\n";
}
function getRowsByArticleSearch($searchString, $table, $max) {
    $con = mysqli_connect("localhost", "user", "password", "db");
    $recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
    if ($getRecords = $con->prepare($recordsQuery)) {
        $getRecords->bind_param("s", $searchString);
        $getRecords->execute();
        $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
        while ($getRecords->fetch()) {
            $result = $con->query($recordsQuery);
            $rows = array();
            while($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            return $rows;
        }
    }
}

나는 이것을 읽으려고 시도했지만 무엇을해야할지 잘 모르겠습니다. 스토어 결과와 무료 결과에 대해 읽었지만 사용할 때 차이가 없었습니다. 이 오류가 정확히 어느 지점에서 발생하는지 확실하지 않으며 그 원인과 해결 방법을 알고 싶습니다.

내 디버그 문으로 가면 countQuery에 대한 첫 번째 if 루프가 근처에있는 내 SQL 구문의 오류로 인해 입력되지 않습니다 '% ? %'. 그러나 *LIKE 절을 기반으로 제한하는 대신 선택하면 여전히 명령이 동기화되지 않습니다.

답변:


114

mysqli는 기본적으로 버퍼링되지 않은 쿼리를 사용하기 때문에 두 개의 동시 쿼리를 가질 수 없습니다 (준비된 명령문의 경우, vanilla의 경우 반대 mysql_query임). 첫 번째 것을 배열로 가져 와서 반복하거나 mysqli에게 쿼리를 버퍼링하도록 지시 할 수 있습니다 (사용 $stmt->store_result()).

자세한 내용은 여기 를 참조 하십시오 .


3
동의합니다. mysqli는 약간의 뇌 손상을 입었습니다. 그것은 하지 비록 PDO MySQL의 드라이버 옳은 일을.

17
두 개의 동시 쿼리를 가질 수 있습니다. 실행하기 만하면 $stmt->store_result();됩니다. 응답이 더 명확해야한다고 생각합니다.
Shadow

3
이 정보를 찾는 데 시간이 많이 걸립니다. 어디에 쉽게 표시되지 않습니다. 감사. 난 그냥 내 쿼리를 분리해서 $select_stmt->close();(동시하지만 절차되지를 분할
n34_panda

@flussence, "mysqli는 기본적으로 버퍼링되지 않은 쿼리를 사용합니다"라고 말씀하셨습니다. 그렇다면 어떻게 다르게 설정할 수 있습니까?
Pacerier

1
이상하게 보이지만 mysqli_query가 외래 키를 위반하는 쿼리를 실행하는 동안이 오류가 발생했습니다. 누군가에게 이런 일이 발생하면 INSERT 쿼리가 외래 키를 위반하지 않는지 다시 확인하십시오
lucaferrario

34

내 C 응용 프로그램 에서이 문제를 해결했습니다. 방법은 다음과 같습니다.

  1. mysql 포럼에서 인용 :

    이 오류 는 응용 프로그램 내에서 세미콜론 구분 기호로 쿼리종료 할 때 발생 합니다 . 명령 줄 또는 쿼리 브라우저에서 실행할 때 세미콜론 구분 기호로 쿼리를 종료해야하지만 응용 프로그램 내부의 쿼리에서 구분 기호를 제거하십시오.

  2. 쿼리를 실행하고 결과 [C API : mysql_store_result()]를 처리 한 후 두 개 이상의 select 문 (결과를 처리하지 않고 연속)과 같은 여러 SQL 문 실행을 통해 발생하는 잠재적으로 보류중인 결과를 반복합니다.

    사실 내 프로시 저는 여러 결과를 반환하지 않지만 [C API : mysql_next_result()]를 실행할 때까지 데이터베이스가이를 알지 못합니다 . 0이 아닌 값을 반환 할 때까지 루프에서이 작업을 수행합니다. 이때 현재 연결 처리기가 다른 쿼리를 실행해도 괜찮다는 것을 알게됩니다 (연결 오버 헤드를 최소화하기 위해 처리기를 캐시합니다).

    이것은 내가 사용하는 루프입니다.

    for(; mysql_next_result(mysql_handler) == 0;) 
      /* do nothing */;
    

나는 PHP를 모르지만 비슷한 것이 있다고 확신합니다.


11
이것은 나를위한 것이었다. PHP에서는 다음을 추가했습니다. while (mysqli_next_result ($ con));
Josh

내 문제를 해결 한 답변에 감사드립니다. 구분 기호를 제거하면 작동합니다. 결과를 해제 (가져 오기)하거나 저장하지 않았지만 쿼리 문 하나를 완료하면 커서를 닫고 다시 빌드합니다.
Chen Xie

@Josh, 레거시 mysql확장 에서 어떻게 수행 합니까?
Pacerier 2015

1
쿼리 끝에서 세미콜론을 제거하면 Python MySQLdb를 사용할 때 "명령이 동기화되지 않았습니다. 지금이 명령을 실행할 수 없습니다"문제가 해결되었습니다.
Genome

17

나는 오늘 같은 문제가 있었지만 저장 프로 시저로 작업 할 때만 발생했습니다. 이렇게하면 쿼리가 다중 쿼리처럼 작동하므로 다른 쿼리를 만들기 전에 사용 가능한 다른 결과를 "소비"해야합니다.

while($this->mysql->more_results()){
    $this->mysql->next_result();
    $this->mysql->use_result();
}

이것은 중요한 점입니다. 저장 프로시 저는 SP의 코드가 생성 할 수있는 모든 결과 집합 위에 결과 집합을 반환합니다. 처리하지 않으면 다음 오류가 발생합니다. stackoverflow.com/a/2315229/4495850
Richard

11

$ mysqli-> query를 사용하기 전에 매번이 함수를 호출합니다. 저장 프로 시저에서도 작동합니다.

function clearStoredResults(){
    global $mysqli;

    do {
         if ($res = $mysqli->store_result()) {
           $res->free();
         }
        } while ($mysqli->more_results() && $mysqli->next_result());        

}

5

사용하면

stmt->execute();

당신은 수도 다른 쿼리를 사용하여 닫습니다.

stmt->close();

이 문제는 몇 시간 동안 나를 사냥하고 있었다. 바라건대, 그것은 당신의 것을 고칠 것입니다.


1
문을 닫을 필요는 없습니다. @stalinbeltran이 위에서 대답했듯이, 우리는 다른 진술을 준비하기 전에 진술의 결과를 "소비"해야합니다. 따라서이 $stmt1->execute(); $stmt2=$conn->prepare(...)오류가 발생하지만 $stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)잘 작동합니다.
Jay Dadhania

형 감사합니다. 이것 저것 말한 모든 사람, 나는 첫 번째 것을 닫기 전에 mysqli_prepare를 두 번 사용했습니다. 효과가있다.
Abhinash Majhi

2

저는 CodeIgniter를 사용합니다. 하나의 서버 OK ... 이것은 아마도 오래된 것입니다 ... 어쨌든 사용

$this->db->reconnect();

고쳤다.


7
이것이 문제를 어떻게 해결합니까?
Jeremy J Starcher

4
@Norman, 이것은 문제를 "수정"하지 않습니다. 그것은 단순한 피합니다 전체 연결을 버리고 다시 다시 연결하여 그것을. 이것은 성능 관점에서 전혀 의미가 없습니다.
Pacerier 2015-06-30

1

문제는 대부분의 MySQL API가 구축 된 MySQL 클라이언트 C 라이브러리입니다. 문제는 C 라이브러리가 쿼리의 동시 실행을 지원하지 않기 때문에 그 위에 구축 된 모든 API도 지원하지 않는다는 것입니다. 버퍼링되지 않은 쿼리를 사용하더라도. 이것이 비동기 MySQL API가 작성된 이유 중 하나입니다. TCP를 사용하여 MySQL 서버와 직접 통신하며 유선 프로토콜 동시 쿼리를 지원합니다.

해결책은 알고리즘을 수정하여 한 번에 둘 다 진행할 필요가 없도록하거나 버퍼링 된 쿼리를 사용하도록 변경하는 것입니다. 이는 아마도 C 라이브러리에 존재하는 원래 이유 중 하나 일 것입니다 (다른 하나는 일종의 커서 제공).


1
나는 한 번에 진행 모두가 없어도, 나는 countQuery 내 두 번째 쿼리하기 전에 완전히 끝날 때까지 행복 해요,하지만 난 proggress에있는에서 countQuery을 중지하는 방법을 확실하지 오전

countQuery에서 데이터를 검색하지 않고 있기 때문에 여전히 '진행 중'입니다. 모든 행을 검색하거나 SELECT COUNT (ARTICLE_NO)로 변경하고 해당 행을 가져 오십시오. 그런 다음 두 번째 쿼리가 실행됩니다.
staticsan

"비동기 MySQL API"라고 말할 때 어떤 API를 의미합니까? 또한 나는 당신의 결론을 얻지 못했습니다. 이 "문제"는 API가 비동기적일 필요없이 수정할 수 있습니다.
Pacerier 2015-06-30

1
솔직히 말해서 @Pacerier 나는 더 이상 내가 의미하는 바가 확실하지 않습니다! MySQL 연결에서 6 년 동안 많은 일이 발생했기 때문에 제가 언급 한 모든 것이 아마도 다른 새 드라이버에 이름이 바뀌거나 통합되었을 것입니다.
staticsan

1

이 문제를 해결하려면 사용하기 전에 결과 데이터를 저장해야합니다.

$numRecords->execute();

$numRecords->store_result();

그게 다야


1

또 다른 원인 : store_result ()를 두 번 호출 할 수 없습니다.

예를 들어, 다음 코드에서는 오류 5가 인쇄됩니다.

<?php

$db = new mysqli("localhost", "something", "something", "something");

$stmt = $db->stmt_init();
if ($stmt->error) printf("Error 1 : %s\n", $stmt->error);

$stmt->prepare("select 1");
if ($stmt->error) printf("Error 2 : %s\n", $stmt->error);

$stmt->execute();
if ($stmt->error) printf("Error 3 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 4 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 5 : %s\n", $stmt->error);

(이것은 원본 샘플 코드와 관련이 없을 수 있지만이 오류에 대한 답을 찾는 사람들과 관련이있을 수 있습니다.)


1

내 문제는 다음과 같습니다!

매개 변수 바인딩은 "동적"이어서 bind_param 을 사용하기 위해 데이터의 매개 변수를 설정하는 변수가 있습니다 . 그래서 그 변수는 잘못되었지만 "잘못된 매개 변수 데이터"와 같은 오류를 던지는 대신 "동기화되지 않은 bla bla bla"라고 표시되어 혼란 스러웠습니다.


0

문제는 함수에서 새로운 연결을 만들고 마지막에 닫지 않는다는 것입니다. 기존 연결을 전달하고 다시 사용하는 것은 어떻습니까?

또 다른 가능성은 while 루프 가져 오기 중간에서 돌아오고 있다는 것입니다. 외부 가져 오기를 완료하지 않습니다.


1
$ con 전역 (나쁜 습관이지만 설명대로 작동해야 함)을 만들면 여전히 동일한 오류가 발생합니다.

1
나는 글로벌 연결이 나쁜 관행이라고 생각하지 않습니다
Mathieu J.

0

모든 매개 변수를 올바르게 입력하고 있는지 확인하십시오. 정의 된 후 함수에 전달되는 매개 변수의 양이 다른 경우 동일한 오류가 발생합니다.


0

이것은 원래 질문과 관련이 없지만 동일한 오류 메시지가 있었고이 스레드는 Google의 첫 번째 히트이며 문제가 무엇인지 파악하는 데 시간이 걸렸으므로 다른 사람들에게 유용 할 수 있습니다.

나는 mysqli를 사용하지 않고 여전히 mysql_connect를 사용하고 있습니다. 몇 가지 간단한 쿼리가 있었지만 하나의 쿼리로 인해 다른 모든 쿼리가 동일한 연결 내에서 실패했습니다.

저는 mysql 5.7과 php 5.6을 사용합니다. 데이터 유형이 "JSON"인 테이블이 있습니다. 분명히 내 php-version은 mysql의 반환 값을 인식하지 못했습니다 (내장 된 mysql-module이 너무 오래 되었기 때문에 PHP는 JSON 형식으로 무엇을 해야할지 몰랐습니다 (적어도 생각합니다))

지금은 JSON-Field-Type을 Text로 변경했으며 (현재는 기본 mysql JSON 기능이 필요하지 않습니다) 모든 것이 잘 작동합니다.


0

당신도 데이터를 가져 오는에 대한 버퍼 또는 언 버퍼 결과 세트를 사용하는 경우, 먼저 당신은 단순히 메모리에서 가져온 데이터를 삭제합니다 모든 데이터를 가져올 일단 . 가져온 메모리를 지울 때까지 동일한 연결에서 다른 MYSQL 프로 시저를 실행할 수 없습니다. 스크립트의 오른쪽 끝에 아래 함수를 추가 하면 문제해결됩니다.

$numRecords->close(); or $numRecords->free(); // This clears the referencing memory, and will be ready for the next MYSQL fetch

PHP 문서의 참조


1
일부 레코드가 필요하지 않다면 처음부터 선택하지 않았어야합니다. 그들을 해제하는 대신 단순히 전혀 선택하지 마십시오. 그렇지 않고 선택한 모든 레코드를 가져 오면 이러한 오류가 전혀 발생하지 않으며 close () 또는 free ()를 호출 할 필요가 없습니다. 저장 프로 시저로, 위의 답변에 설명 덜 야만적 인 방법이있다
당신의 상식

0

Doctrine DBAL QueryBuilder를 사용하여이 오류가 발생했습니다.

열 하위 선택을 사용하는 QueryBuilder로 쿼리를 만들었으며 QueryBuilder로도 생성했습니다. 하위 선택은를 통해서만 생성되었으며 $queryBuilder->getSQL()실행되지 않았습니다. 두 번째 하위 선택을 만들 때 오류가 발생했습니다. $queryBuilder->execute()사용하기 전에 각 하위 선택을 임시로 실행 $queryBuilder->getSQL()하면 모든 것이 작동했습니다. $queryBuilder->connection각 하위 선택의 새 QueryBuilder 인스턴스에도 불구하고 현재 준비된 SQL을 실행하기 전에 새 SQL을 생성하기위한 연결 이 잘못된 상태로 남아있는 것과 같습니다.

내 해결책은 QueryBuilder없이 하위 선택을 작성하는 것이 었습니다.


0

ODBC를 사용하고 있으며이 수정 사항이 저에게 효과적입니다. ODBC-> 시스템 DSN 탭-> 데이터 소스 구성-> 세부 정보-> 커서 탭-> [정방향 전용 커서의 결과 캐시 안 함 ] 선택 취소 - > 확인 클릭


0

나는 종종이 오류가 발생했으며 phpmyadmin 또는 SQL Workbench에서 디버깅 한 저장 프로 시저를 실행할 때 항상 발생합니다 (mysqli와 연결하는 PHP에서 작업 중입니다).

이 오류는 디버깅시 코드의 전략적 지점에 SELECT 문을 삽입하여 변수의 상태 등을 알려주기 때문에 발생합니다. 이러한 클라이언트 환경에서 여러 결과 집합을 생성하는 저장 프로 시저를 실행하는 것은 괜찮지 만 " php에서 호출 할 때 "동기화되지 않은 명령"오류가 발생합니다. 해결책은 항상 디버깅 선택 항목을 주석 처리하거나 제거하여 프로 시저에 결과 집합이 하나만 있도록하는 것입니다.


-1

내 문제는 내가 first prepare 문을 사용하고 있었고 같은 페이지에서 mysqli 쿼리를 사용하고 있었고 "Commands out of sync; you ca n't run this command now"라는 오류가 발생했습니다. 오류는 prepare 문이있는 코드를 사용할 때만 발생했습니다.

내가 한 일은 질문을 종결하는 것이 었습니다. 그리고 그것은 작동했습니다.

mysqli_stmt_close ($ stmt);

내 코드

get_category.php (여기에서 prepare 문 사용)

    <?php


    global $connection;
    $cat_to_delete =    mysqli_real_escape_string($connection, $_GET['get'] );

    $sql = "SELECT category_name FROM categories WHERE category_id = ? ;";


    $stmt = mysqli_stmt_init($connection);

    if (!mysqli_stmt_prepare($stmt, $sql))
        $_SESSION['error'] = "Error at preaparing for deleting query. mysqli_stmt_error($stmt) ." & redirect('../error.php');

    mysqli_stmt_bind_param($stmt, 's', $cat_to_delete);

    if (!mysqli_stmt_execute($stmt))
        $_SESSION['error'] = "ERror at executing delete category ".mysqli_stmt_error($stmt) &
            redirect('../error.php');


    mysqli_stmt_bind_result($stmt, $cat_name);

    if (!mysqli_stmt_fetch($stmt)) {
        mysqli_stmt_error($stmt);
    }



    mysqli_stmt_free_result($stmt);
    mysqli_stmt_close($stmt);

admin_get_category_body.php (여기 mysqli)

        <?php

        if (isset($_GET['get']) && !empty($_GET['get']) )
        {
            include 'intodb/edit_category.php';
        }


        if (check_method('get') && isset($_GET['delete']) )
        {
            require 'intodb/delete_category.php';
        }


        if (check_method('get') && isset($_GET['get']) )
        {
            require 'intodb/get_category.php';
        }


        ?>

        <!--            start: cat body          -->

        <div     class="columns is-mobile is-centered is-vcentered">
            <div class="column is-half">
                <div   class="section has-background-white-ter box ">


                    <div class="has-text-centered column    " >
                        <h4 class="title is-4">Ctegories</h4>
                    </div>

                    <div class="column " >


                        <?php if (check_method('get') && isset($_GET['get'])) {?>
                        <form action="" method="post">
                            <?php } else {?>
                            <form action="intodb/add_category.php" method="post">
                                <?php } ?>

                                <label class="label" for="admin_add_category_bar">Add Category</label>
                                <div class="field is-grouped">

                                    <p class="control is-expanded">

                                        <?php if (check_method('get') && isset($_GET['get'])) {?>

                                            <input id="admin_add_category_bar" name="admin_add_category_bar_edit" class="input" type="text" placeholder="Add Your Category Here" value="<?php echo $cat_name; ?>">

                                            <?php


                                            ?>
                                        <?php } else {?>
                                            <input id="admin_add_category_bar" name="admin_add_category_bar" class="input" type="text" placeholder="Add Your Category Here">

                                        <?php } ?>
                                    </p>
                                    <p class="control">
                                        <input type="submit" name="admin_add_category_submit" class="button is-info my_fucking_hover_right_arrow" value="Add Category">
                                    </p>
                                </div>
                            </form>


                            <div class="">

                                <!--            start: body for all posts inside admin          -->


                                <table class="table is-bordered">
                                    <thead>
                                    <tr>
                                        <th><p>Category Name</p></th>
                                        <th><p>Edit</p></th>
                                        <th><p>Delete</p></th>
                                    </tr>
                                    </thead>

                                    <?php

                                    global $connection;
                                    $sql = "SELECT * FROM categories ;";

                                    $result = mysqli_query($connection, $sql);
                                    if (!$result) {
                                        echo mysqli_error($connection);
                                    }
                                    while($row = mysqli_fetch_assoc($result))
                                    {
                                        ?>
                                        <tbody>
                                        <tr>
                                            <td><p><?php echo $row['category_name']?></p></td>
                                            <td>
                                                <a href="admin_category.php?get=<?php echo $row['category_id']; ?>" class="button is-info my_fucking_hover_right_arrow" >Edit</a>

                                            </td>

                                            <td>
                                                <a href="admin_category.php?delete=<?php echo $row['category_id']; ?>" class="button is-danger my_fucking_hover_right_arrow" >Delete</a>

                                            </td>
                                        </tr>


                                        </tbody>
                                    <?php }?>
                                </table>

                                <!--           end: body for all posts inside admin             -->




                            </div>

                    </div>
                </div>


            </div>

        </div>
        </div>

방금 생각했던 것, 나는 또한 전역 $ connection;을 통해 연결 변수를 다시 추가하고 있습니다. 그래서 기본적으로 mysqli_stmt_close ($ stmt); 준비 문이 끝난 후 완전히 새로운 쿼리 시스템 세트가 시작되고 있다고 생각합니다. 또한 include를 통해 이러한 파일 및 기타 항목을 추가하고 있습니다.


get_category.php (여기에서 prepare 문 사용) pastebin.com/BiWysdYz admin_get_category_body.php (mysqli) pastebin.com/Pwm30icm 참고 : 제한으로 인해 모든 코드를 게시 할 수 없습니다
Mahad Ali

방금 생각했던 것, 나는 또한 전역 $ connection;을 통해 연결 변수를 다시 추가하고 있습니다. 그래서 기본적으로 mysqli_stmt_close ($ stmt); 준비 문이 끝난 후 완전히 새로운 쿼리 시스템 세트가 시작되고 있다고 생각합니다. 또한 include를 통해 이러한 파일과 기타 항목을 추가하고 있습니다.
Mahad Ali

-1

이것은 오래된 질문이지만 게시 된 답변 중 어느 것도 제 경우에는 작동하지 않았습니다. 제 경우에는 저장 프로 시저의 테이블에 대한 선택 및 업데이트가 있었고 동일한 테이블에 트리거되고 senging되는 업데이트 트리거가 있음을 발견했습니다. 무한 루프로 절차. 버그가 발견되면 오류가 사라졌습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.