Сообщение об ошибке синтаксиса MySQL «Операнд должен содержать 1 столбец (и)» - PullRequest
22 голосов
/ 19 января 2009

Я попытался выполнить следующую инструкцию:

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:

Структура книги:

ID  int(11)
START_NUMBER    int(11)
UNITS   int(11)
DENOMINATION    double(5,2)

Структура temp_cheques:

ID  int(11)
number  varchar(20)

Ответы [ 5 ]

48 голосов
/ 19 января 2009

Попробуйте удалить скобки из предложения 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 перед выполнением этого оператора и повторите попытку. Это должно работать, но учтите, что эта операция может занять много времени.

3 голосов
/ 19 января 2009

Содержит ли столбец B ЕДИНИЦЫ?

Какова структура таблицы для temp_cheques и Book?

РЕДАКТИРОВАТЬ: Как я сказал в комментариях, все столбцы должны быть числовыми при выполнении +/- и при сравнении.
Работает ли следующий простой SELECT?

SELECT b.START_NUMBER+b.UNITS-1 FROM Books B

2 голосов
/ 19 января 2009

Окончательная версия запроса выглядит следующим образом:

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 в BOOK) я нарушил ограничение на размер выбора, требуя от меня установки SQL_BIG_SELECTS = 1.

2 голосов
/ 19 января 2009

У меня нет удобного экземпляра 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);
1 голос
/ 04 июля 2018

Я столкнулся с той же ошибкой при использовании репозиториев Spring.

Мой репозиторий содержал метод, подобный:

List<SomeEntity> findAllBySomeId(List<String> ids);

Это нормально работает при запуске интеграционных тестов для базы данных в памяти (h2). Однако для автономной базы данных, такой как MySql, произошел сбой с той же ошибкой.

Я решил это, изменив интерфейс метода на:

List<someEntity findBySomeIdIn(List<String> ids);

Примечание: между find и findAll нет никакой разницы. Как описано здесь: Разница в JPA данных Spring между findBy / findAllBy

...