如何让MySQLi返回有关处理SQL查询文件时返回的错误的更多详细信息


How do I get MySQLi to return more detail about an error returned whilst processing a file of SQL queries?

我们有一个初始化测试数据库的方法,如下所示:

    $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实现这一点?

您必须拆分多查询字符串并单独运行查询。AFAIK无法从MySQLi中提取查询。很明显,您可以在;上进行拆分,但这可能会导致错误(例如,如果您的某个查询使用包含;的字符串),并且您确实需要确保您的test-data.sql文件包含由永远不会出现在查询中的内容分隔的字符串。

一种安全的方法是在;'n上进行拆分,并确保所有查询都用新行分隔,并且文本新行永远不会出现在查询中-本质上确保始终使用'n(无论如何都应该这样做)。

例如(注意:我不确定store_result()在这里如何工作,甚至是否工作-我已经做了最好的猜测,但这是未经测试的,可能需要调整)

测试数据.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);
    }
}