Как я могу получить MySQLi для получения более подробной информации об ошибке, возвращенной при обработке файла SQL-запросов? - PullRequest
0 голосов
/ 20 января 2012

У нас есть метод, который инициализирует тестовую базу данных следующим образом:

    $db=file_get_contents('test-data.sql');

    /* @var $result mysqli_result */
    $result=self::$_mysqlConn->multi_query($db);
    if (!$result) {
        fwrite(STDERR, self::$_mysqlConn->error."\nBUILD FAILED!\n");
        exit(1);
    }

    while ($nextResRes = self::$_mysqlConn->next_result()) {
        $tempRes = self::$_mysqlConn->store_result();
        if (!self::$_mysqlConn->more_results()) break;
    }

    if (self::$_mysqlConn->errno) {
        fwrite(STDERR, "DB QUERIES FAILED. FILE: ".$file."\n");
        fwrite(STDERR, self::$_mysqlConn->error."\nBUILD FAILED!\n");
        exit(1);
    }

Сборка в настоящее время не выполняется из-за одного из запросов в файле data.sql. Возвращаемая ошибка не очень полезна:

DB QUERIES FAILED. FILE: data
Column count doesn't match value count at row 1
BUILD FAILED!

Я бы хотел как-то вывести конкретный запрос, который на данный момент не смог STDERR. Как мне добиться этого с MySQLi?

1 Ответ

1 голос
/ 20 января 2012

Вам придется разделить строку с несколькими запросами и выполнить запросы по отдельности. AFAIK нет способа извлечь запрос из MySQLi. Очевидно, вы могли бы просто разделить на ;, но это может привести к ошибкам (например, если один из ваших запросов использует строку, содержащую ;), и вам действительно нужно убедиться, что ваш файл test-data.sql содержит строки, разделенные чем-то, что никогда не появится в запросе.

Один из подходов к этому, который должен быть безопасным, - это разделить на ;\n и убедиться, что все ваши запросы разделены новыми строками, а буквальная новая строка никогда не появляется в запросе - по существу, убедитесь вы всегда используете \n (что вы должны сделать в любом случае).

Например ( Примечание: я не уверен, как или даже если store_result() будет работать здесь - я сделал наилучшее предположение, но это не проверено и, возможно, потребуется адаптировать) :

тест-data.sql

INSERT INTO someTable
  (col1, col2, col3)
VALUES
  ('val1', 'val2', 'val3');

UPDATE someTable SET col1 = 'val' WHERE id = 4;

DELETE FROM someTable WHERE id > 7;

PHP

// Get data from file and create an array of queries
$db = file_get_contents('test-data.sql');
$queries = explode(";\n", $db);

// Loop queries
foreach ($queries as $query) {

    // Trim whitespace and skip empty queries (mostly useful for last one)
    if (($query = trim($query)) === '') continue;

    // Do this query
    $result = self::$_mysqlConn->query($query);
    if (!$result) {
        fwrite(STDERR, self::$_mysqlConn->error."\nQuery: $query\nBUILD FAILED!\n");
        exit(1);
    }

    // Store result (?)
    self::$_mysqlConn->store_result();

    // This may not be the best place for this and it may not even be required
    // any more - that's a decision for you really
    if (self::$_mysqlConn->errno) {
        fwrite(STDERR, "DB QUERIES FAILED. FILE: ".$file."\n");
        exit(1);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...