Сообщение об ошибке синтаксиса MySQL " операнд должен содержать 1 столбец(ы)"
Я попытался выполнить следующее утверждение:
INSERT INTO VOUCHER (VOUCHER_NUMBER, BOOK_ID, DENOMINATION)
SELECT (a.number, b.ID, b.DENOMINATION)
FROM temp_cheques a, BOOK b
WHERE a.number BETWEEN b.START_NUMBER AND b.START_NUMBER+b.UNITS-1;
который, как я понимаю, должен вставлять в ваучер каждую запись из temp_cheques с полями ID и деноминации, соответствующими записям в таблице BOOK (temp_cheques происходит из резервной копии базы данных, которую я пытаюсь воссоздать в другом формате). Однако, когда я запускаю его, я получаю сообщение об ошибке:
Error: Operand should contain 1 column(s)
SQLState: 21000
ErrorCode: 1241
Я запускаю это в SQuirrel и не имел проблем с любыми другими запросами. Быть там что-то не так с синтаксисом запроса?
EDIT:
структура книги:
ID int(11)
START_NUMBER int(11)
UNITS int(11)
DENOMINATION double(5,2)
структура temp_cheques:
ID int(11)
number varchar(20)
5 ответов
Попробуйте удалить скобки из предложения SELECT. От Microsoft TechNet, правильный синтаксис инструкции INSERT с помощью предложения SELECT следующий.
INSERT INTO MyTable (PriKey, Description)
SELECT ForeignKey, Description
FROM SomeView
ошибка, которую вы получаете: "выбор будет проверять больше строк MAX_JOIN_SIZE; проверьте, где и используйте SET SQL_BIG_SELECTS=1 или SET SQL_MAX_JOIN_SIZE=#, если выбор в порядке.", на самом деле правильно, предполагая, что у вас много строк как в книге, так и в temp_cheques. Вы пытаетесь чтобы запросить все строки из обеих таблиц и сделать перекрестную ссылку, в результате чего запрос размера m*n. SQL Server пытается предупредить вас об этом перед выполнением потенциально длительной операции.
Set SQL_BIG_SELECTS
= 1 перед запуском этого оператора и повторите попытку. Он должен работать, но обратите внимание, что эта операция может занять много времени.
содержит ли B столбец единиц?
какова структура таблицы для temp_cheques и Book?
EDIT: как я сказал в комментариях, все столбцы должны быть числовыми при выполнении +/- и при сравнении.
работает ли следующий простой выбор?
SELECT b.START_NUMBER+b.UNITS-1 FROM Books B
у меня нет экземпляра MySQL, но мое первое предположение-предложение WHERE:
WHERE a.number BETWEEN b.START_NUMBER AND b.START_NUMBER+b.UNITS-1;
Я предполагаю, что парсер MySQL может интерпретировать это как:
WHERE number
(BETWEEN start_number AND start_number) + units - 1
попробуйте обернуть все в скобки, т. е.:
WHERE a.number BETWEEN b.START_NUMBER AND (b.START_NUMBER + b.UNITS - 1);
окончательная версия запроса выглядит следующим образом:
Set SQL_BIG_SELECTS = 1;
INSERT INTO VOUCHER (VOUCHER_NUMBER, BOOK_ID, DENOMINATION)
SELECT a.number, b.ID, b.DENOMINATION
FROM temp_cheques a, BOOK b
WHERE a.number BETWEEN b.START_NUMBER AND (b.START_NUMBER+b.UNITS-1);
синтаксический анализ оператора BETWEEN требует скобок, SELECT не сделал, и из-за размера двух таблиц (215000 записей в temp_cheques, 8000 в книге) я нарушал ограничение на размер select, требуя от меня установить SQL_BIG_SELECTS = 1.
я столкнулся с той же ошибкой при использовании репозиториев Spring.
мой репозиторий содержал такой метод, как:
List<SomeEntity> findAllBySomeId(List<String> ids);
это отлично работает при выполнении интеграционных тестов с базой данных в памяти (h2). Однако против автономной базы данных, такой как MySql, произошел сбой с той же ошибкой.
Я решил это, изменив интерфейс метода на:
List<someEntity findBySomeIdIn(List<String> ids);
Примечание: нет никакой разницы между find
и findAll
. Как описано здесь: весенние данные JPA разница между findBy / findAllBy