【问题标题】:Batch Inserts And Prepared Query Error批量插入和准备好的查询错误
【发布时间】:2011-03-05 12:00:01
【问题描述】:

好的,所以我需要使用 MySQL 查询的结果填充 MS Access 数据库表。这一点都不难。我已将程序写入将模板 .mdb 文件复制到临时名称并通过 odbc 打开它的位置。目前没问题。

我注意到 Access 不支持批量插入 (VALUES (foo, bar), (second, query), (third query))。所以这意味着我需要每行执行一个查询(可能有数十万行)。初始性能测试显示 Access 的插入速率约为 900 次/秒。对于我们最大的数据集,这可能意味着几分钟的执行时间(这不是世界末日,但显然越快越好)。

所以,我尝试测试一个准备好的语句。但我不断收到错误消息 (Warning: odbc_execute() [function.odbc-execute]: SQL error: [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect , SQL state 07001 in SQLExecute in D:\....php on line 30)。

这是我正在使用的代码(第 30 行是 odbc_execute):

$sql = 'INSERT INTO table 
    ([field0], [field1], [field2], [field3], [field4], [field5]) 
    VALUES (?, ?, ?, ?, ?, ?)';
$stmt = odbc_prepare($conn, $sql);
for ($i = 200001; $i < 300001; $i++) {
    $a = array($i, "Field1 $", "Field2 $i", "Field3 $i", "Field4 $i", $i);
    odbc_execute($stmt, $a);
}

所以我的问题有两个方面。首先,是否知道为什么会出现该错误(我已经检查过,数组中的数字与与参数? 标记数匹配的字段列表匹配)?其次,我应该为此烦恼还是只使用直接的 INSERT 语句?就像我说的,时间并不重要,但如果可能的话,我希望尽可能缩短时间(再说一次,我可能会受到磁盘吞吐量的限制,因为 900 次操作/秒已经很高了).. .

谢谢

【问题讨论】:

    标签: php ms-access odbc prepared-statement batch-insert


    【解决方案1】:

    您需要逐行执行此操作吗?为什么不一次插入所有数据?

    What is the best way to synchronize data between MS Access and MySQL?

    【讨论】:

    • 哇!你能做到吗?现在,我的 MySQL 查询非常复杂。我需要用 Access 语法写吗?还是我用 MySQL 语法编写它,但通过 Access 执行它?我绝对不想逐行执行(如果必须的话,很好),但是生成结果的查询有 2 到 8 个连接,以及不同数量的 where 子句(和 group by 子句)诡计......即使这看起来仍然是一条有趣的路线......
    • 您应该能够在Access中执行直通查询,或者使用ADO和MySQL连接字符串,在这种情况下您可以参考Access with IN。我不确定你想从哪里开始,所以提供更多细节有点困难。
    • 我会在周一解决这个问题,如果遇到问题,请发布一个新问题...谢谢!
    • 据我回忆,MySQL 无法访问 ODBC 数据,除非在另一个 MySQL 数据库中,因此您需要在 Access 中创建 ODBC 链接表(到 MySQL 目标表)并告诉 Access通过 ODBC 运行 SQL。
    • 这是一个复杂的查询,所以我认为 Access 不一定是最好的地方,但是在 Access 中使用 MySQL 连接字符串并不难。
    【解决方案2】:

    PHP 是否提供了一种查看参数替换后正在执行的 INSERT 语句的方法?我认为您可能没有在 VALUES 列表中获得围绕文本值的引号。如果没有引号,Jet 数据库引擎会将“Field1 200001”解释为两个值,而不是一个。

    另外,我不懂 PHP,但你的数组的第二个成员应该是“Field1 $i”而不是“Field1 $”吗?

    你能从 PHP 中执行这个语句吗?它有效吗?

    INSERT INTO table 
        ([field0], [field1], [field2], [field3], [field4], [field5]) 
    VALUES (
        200001,
        'Field1 200001',
        'Field2 200001',
        'Field3 200001',
        'Field4 200001',
        200001);
    

    这个怎么样?

    $sql = 'INSERT INTO table 
        ([field0], [field1], [field2], [field3], [field4], [field5]) 
        VALUES (?, "?", "?", "?", "?", ?)';
    

    【讨论】:

    • 不是我发现的。由于它正在写入本地文件,因此我什至无法对其进行wireshark(据我所知)......
    • 在这种情况下,我怀疑问题 INSERT 语句是在没有引用文本值的情况下提交给 Jet 的。不幸的是,我不知道如何从 PHP 中解决这个问题。
    • 在 values 语句中在 ? 周围添加引号显示与以前相同的错误...我不确定发生了什么。关于另一个问题的任何建议(我应该打扰,还是插入率相同)?
    • 不,我只是专注于让它工作。怕我卡住了。很遗憾,您不能在 Access 中执行此操作;链接到您的 MySql 表并使用它来运行插入到 Jet 表中可能很简单。
    • 我查看了 odbc_prepare 的 PHP 文档。它讨论了与存储过程的使用。由于 Jet 不支持我们通常认为的存储过程,我怀疑 odbc_prepare 在这里是否有用。由于我建议的那个语句有效,因此构建您的语句并为每一行执行。我猜测进行 Jet 插入所需的时间,而不是 PHP 构建每个 INSERT 语句字符串所需的时间,将是您的瓶颈。
    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 2011-11-03
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2020-10-27
    • 2018-03-02
    相关资源
    最近更新 更多