SQLITE_RANGE: 绑定或列超出 INSERT 语句的范围

SQLITE_RANGE: bind or column out of range for INSERT statement

我想使用 knex.raw 方法将行插入到 SQLite3 table 中。不幸的是,我收到 'SQLITE_RANGE' 错误,这使我的测试失败。 我已经通过以下方式验证了传递给原始查询的绑定:

除此之外,我已经在网上查看过,但找不到解决我的问题的方法。以下是尝试操作的详细信息:

错误:

SQLITE_RANGE: bind or column index out of range errno: 25, code: 'SQLITE_RANGE'

Table定义:

-- --------------------------------------------------------

--
-- Table structure for table `ds13odba`
--

CREATE TABLE IF NOT EXISTS `ds13odba` (
  `SURGERY_CODE` VARCHAR(6) ,
  `TYPE` VARCHAR(1) ,
  `FP59STALIB` VARCHAR(6) ,
  `ID` INT UNSIGNED NOT NULL ,
  `createdAt` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
  `updatedAt` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL

);

-- --------------------------------------------------------

*请注意,此处定义的列类型是亲和类型,即MySQL类型。这些在 SQLite3 中有效,并由引擎转换和优化为 SQLite3 中的等价物。

查询:

INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);
INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);
INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);

绑定:

[ 
  '047202', 1, '000001', 'D',
  '047203', 2, '000002', 'D',
  '047204', 3, '000003', 'D' 
]

调用代码:

await knex.raw(...convertToInsertSQL(records));

解析为:

await knex.raw(insertStatements.join('\n'), bindings);

你能帮我解决这个问题吗?

干杯

我没有发现您发布的信息有任何明显的错误,但您没有发布实际的 .raw() 语句,这有助于调试。

因此,为了提供帮助,我建议您添加一个 .on('query-error'... 子句,如下所示,它将记录失败的 SQL。很多时候这会使问题变得明显。

knex.raw(...your-stuff...)
    .on('query-error', function(ex, obj) {
        console.log("KNEX-query-error ex:", ex, "obj:", obj);
    })

祝你好运!

问题源于 SQLite3 不支持每次 exec() 调用 multi-statements,如记录 here

经过我这边的一些测试,我发现 SQLite3 引擎会自动将所有绑定分配给准备好的 SQL[=28= 的第一条语句].以下任何语句都将被忽略。

这仍然适用于事务,因为绑定将应用于 'BEGIN TRANSACTION;' 语句而不是以下语句。

解决方案是使用带绑定的复合 INSERT 语句。

因此:

INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);
INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);
INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE) VALUES (?,?,?,?);

变成这样:

INSERT INTO `ds13odba` (FP59STALIB, ID, SURGERY_CODE, TYPE)
  VALUES (?,?,?,?), (?,?,?,?), (?,?,?,?);

*请记住,复合 INSERT 语句仅适用于 SQLite3 引擎的 3.7.11 版。