web-dev-qa-db-fra.com

Message d'erreur de la syntaxe MySQL "L'opérande doit contenir 1 colonne (s)"

J'ai essayé d'exécuter la déclaration suivante:

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;

qui, si je comprends bien, doit insérer dans VOUCHER chaque enregistrement de temp_cheques avec les champs ID et DENOMINATION correspondant aux entrées de la table BOOK (temp_cheques provient d'une sauvegarde de la base de données, que j'essaie de recréer dans un format différent). Cependant, lorsque je l'exécute, j'obtiens une erreur:

Error: Operand should contain 1 column(s)
SQLState:  21000
ErrorCode: 1241

J'exécute cela dans SQuirrel et je n'ai eu aucun problème avec d'autres requêtes. Y a-t-il un problème avec la syntaxe de ma requête?

ÉDITER:

La structure de BOOK est la suivante:

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

La structure de temp_cheques est:

ID  int(11)
number  varchar(20)
23
Elie

Essayez de supprimer la parenthèse de la clause SELECT. De Microsoft TechNet , la syntaxe correcte pour une instruction INSERT utilisant une clause SELECT est la suivante.

INSERT INTO MyTable  (PriKey, Description)
       SELECT ForeignKey, Description
       FROM SomeView

L'erreur que vous obtenez, "le SELECT examinerait plus de MAX_JOIN_SIZE lignes; vérifiez votre OERE et utilisez SET SQL_BIG_SELECTS = 1 ou SET SQL_MAX_JOIN_SIZE = # si le SELECT est correct.", Est en fait correcte, en supposant que vous avez plusieurs lignes dans les deux BOOK et temp_cheques. Vous essayez d'interroger toutes les lignes des deux tables et de créer une référence croisée, ce qui entraîne une requête de taille m * n. SQL Server essaie de vous en avertir avant d'effectuer une opération potentiellement longue.

Ensemble SQL_BIG_SELECTS = 1 avant d'exécuter cette instruction et réessayez. Cela devrait fonctionner, mais notez que cette opération peut prendre un certain temps.

52
lc.

B contient-il la colonne UNITS?

Quelle est la structure de la table pour temp_cheques et Book?

EDIT: Comme je l'ai dit dans les commentaires, toutes les colonnes doivent être numériques lorsque vous faites +/- et lorsque vous comparez.
Le simple SELECT suivant fonctionne-t-il?

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

3
shahkalpesh

La version finale de la requête est la suivante:

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

L'analyse de l'instruction BETWEEN nécessitait des parenthèses, pas SELECT, et en raison de la taille des deux tables (215000 enregistrements dans temp_cheques, 8000 dans BOOK), je dépassais une limite sur la taille sélectionnée, m'obligeant à définir SQL_BIG_SELECTS = 1 .

2
Elie

Je n'ai pas d'instance MySQL à portée de main, mais ma première supposition est la clause WHERE:

WHERE a.number BETWEEN b.START_NUMBER AND b.START_NUMBER+b.UNITS-1;

J'imagine que l'analyseur MySQL peut interpréter cela comme:

WHERE number
(BETWEEN start_number AND start_number) + units - 1

Essayez de tout mettre entre parenthèses, c'est-à-dire:

WHERE a.number BETWEEN b.START_NUMBER AND (b.START_NUMBER + b.UNITS - 1);
2
RJHunter

J'ai rencontré la même erreur lors de l'utilisation de Spring Repositories.

Mon référentiel contenait une méthode comme:

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

Cela fonctionne correctement lors de l'exécution de tests d'intégration sur une base de données en mémoire (h2). Cependant contre une base de données autonome comme MySql échouait avec la même erreur.

Je l'ai résolu en changeant l'interface de méthode en:

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

Remarque: il n'y a pas de différence entre find et findAll. Comme décrit ici: différence Spring Data JPA entre findBy/findAllBy

1
Pim Hazebroek