Подтвердить что ты не робот

Сообщение об ошибке синтаксиса 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)
4b9b3361

Ответ 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