24

次のステートメントを実行してみました。

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;

私が理解しているように、これは、BOOK テーブルのエントリに対応する ID および DENOMINATION フィールドを持つ temp_cheques の各レコードを VOUCHER に挿入する必要があります (temp_cheques は、別の形式で再作成しようとしているデータベースのバックアップから取得されます)。ただし、実行するとエラーが発生します。

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

これを SQuirrel で実行していますが、他のクエリで問題は発生していません。クエリの構文に何か問題がありますか?

編集:

BOOK の構造は次のとおりです。

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

temp_cheques の構造は次のとおりです。

ID  int(11)
number  varchar(20)
4

5 に答える 5

58

SELECT句から括弧を削除してみてください。Microsoft TechNetから、SELECT句を使用したINSERTステートメントの正しい構文は次のとおりです。

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

「SELECTはMAX_JOIN_SIZEを超える行を調べます。WHEREを確認し、SELECTが正常な場合はSET SQL_BIG_SELECTS=1またはSETSQL_MAX_JOIN_SIZE=#を使用してください。」というエラーは、両方に多くの行があると仮定すると、実際には正しいです。 BOOKとtemp_cheques。両方のテーブルからすべての行をクエリして相互参照を作成しようとすると、m*nサイズのクエリが発生します。SQL Serverは、長時間の操作を実行する前に、これを警告しようとしています。

SQL_BIG_SELECTSこのステートメントを実行する前に=1に設定して、再試行してください。動作するはずですが、この操作には時間がかかる場合がありますのでご注意ください。

于 2009-01-19T06:34:55.360 に答える
3

B には UNITS 列が含まれていますか?

temp_cheques と Book のテーブル構造は何ですか?

編集:コメントで述べたように、+/- を実行するときと比較するときは、すべての列を数値にする必要があります。
次の単純な SELECT は機能しますか?

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

于 2009-01-19T05:58:48.490 に答える
2

クエリの最終バージョンは次のとおりです。

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は必要ありませんでした。また、2つのテーブルのサイズ(temp_chequesでは215000レコード、BOOKでは8000レコード)のため、selectサイズの制限を超えていたため、SQL_BIG_SELECTS=1を設定する必要がありました。 。

于 2009-01-19T06:33:19.717 に答える
2

手元に 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);
于 2009-01-19T06:11:29.057 に答える