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