SQLITE_RANGE: bind or column out of range for INSERT statement

送分小仙女□ 提交于 2019-12-13 02:49:57

问题


I want to insert rows into a SQLite3 table using the knex.raw method. Unfortunately I get a 'SQLITE_RANGE' error, which makes my test fail. I have verified the bindings passed to the raw query in the following fashion:

  • They respect the order of the INSERT statement
  • They respect the specified column types
  • They respect the number of bindings requested in the raw query

Beyond that I have looked online, but couldn't find a solution to my issue. Below are the details of the operation attempted:

  • Engine: sqlite3 ^3.1.13
  • SQL Client: knex ^0.14.4
  • Environment: electron ^1.7.11

Error:

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

Table definition:

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

--
-- 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

);

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

*Take note that the column types defined here are affinity types, i.e. MySQL types. These are valid in SQLite3 and are casted and optimized by the engine to their equivalent in SQLite3.

Query:

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 (?,?,?,?);

Bindings:

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

Calling code:

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

Which resolves to:

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

Could you help me with this issue?

Cheers 🦋


回答1:


I don't see anything obviously wrong with the info you've posted, but you haven't posted the actual .raw() statements, which would help with debugging.

So attempting to assist, I would suggest that you add an .on('query-error'... clause like that below, which will log the SQL that is failing. Many times this will make the problem obvious.

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

Good luck!




回答2:


The issue stems from SQLite3's lack of support of multi-statements per exec() call, as documented here.

After some testing on my end, I discovered that the SQLite3 engine will assign automatically all the bindings to the first statement of the prepared SQL. Any following statements will be ignored.

This still applies for transactions, as the bindings will be applied to the 'BEGIN TRANSACTION;' statement rather than to the following statements.

The solution is to use a compound INSERT statement with bindings.

Hence this:

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 (?,?,?,?);

becomes this:

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

*Bear in mind that compound INSERT statements are only available as of version 3.7.11 of the SQLite3 engine.



来源:https://stackoverflow.com/questions/49156991/sqlite-range-bind-or-column-out-of-range-for-insert-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!