SQLITE_RANGE: привязка или столбец вне диапазона для оператора INSERT

Я хочу вставить строки в таблицу SQLite3, используя knex.raw метод. К сожалению, я получаю ошибку "SQLITE_RANGE", из-за которой мой тест не пройден. Я проверил привязки, переданные необработанному запросу, следующим образом:

  • Они уважают порядок заявления INSERT
  • Они уважают указанные типы столбцов
  • Они учитывают количество привязок, запрошенных в необработанном запросе.

Кроме того, я посмотрел онлайн, но не смог найти решение своей проблемы. Ниже приведена подробная информация о предпринятой операции:

Ошибка:

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

Определение таблицы:

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

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

Не могли бы вы помочь мне с этим вопросом?

ура

2 ответа

Решение

Эта проблема связана с отсутствием поддержки SQLite3 мульти-операторов на вызов exec(), как описано здесь.

Проведя некоторое тестирование с моей стороны, я обнаружил, что движок SQLite3 автоматически назначит все привязки для первого оператора подготовленного SQL. Любые последующие утверждения будут игнорироваться.

Это относится и к транзакциям, так как привязки будут применены к "НАЧАЛО СДЕЛКИ"; утверждение, а не следующие утверждения.

Решение состоит в том, чтобы использовать составной оператор 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 доступны только начиная с версии 3.7.11 механизма SQLite3.

Я не вижу ничего явно неправильного в информации, которую вы разместили, но вы не опубликовали фактическую .raw() заявления, которые помогли бы с отладкой.

Поэтому, пытаясь помочь, я бы предложил вам добавить .on('query-error'... предложение, подобное приведенному ниже, которое будет регистрировать SQL, который не работает. Много раз это сделает проблему очевидной.

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

Удачи!

Другие вопросы по тегам