2009-05-22 10 views
1

私は、次の表を持っている:のMySQL:UNIQUE制約とSELECT ... INSERT INTOと入力エラーを複製

CREATE TABLE `products_quantity` (
    `id` int(11) NOT NULL auto_increment, 
    `product_id` varchar(100) NOT NULL, 
    `stock_id` int(11) NOT NULL, 
    `quantity` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `product_id` (`product_id`,`stock_id`), 
    KEY `products_quantity_product_id` (`product_id`), 
    KEY `products_quantity_stock_id` (`stock_id`) 
) ENGINE=MyISAM 

のproduct_idは、別のテーブルへの外部キーであり、従ってstock_idです。

この表には、すべて同じStock_id(1)を持つ10000以上の行があります。私がしようとしているのは、すべての行を2回複製し、両方とも新しい在庫ID(2と3)、および「数量」のランダム値を複製することです。

INSERT INTO `products_quantity` (product_id, stock_id, quantity) 
    SELECT product_id, 2 AS stock_id, FLOOR(-1 + (RAND() * 15)) AS random_quantity FROM products_quantity; 

正常に動作します:ここで

はSQLです。別のstock_idを持つ10,000個以上の新しい行を作成するため、各行のproduct_idはすでに存在していますが、一意制約は違反されません。

22  0032705090062 1 1 
10783 0032705090062 2 13 
21  0032705090345 1 6 
10784 0032705090345 2 0 
... 

一度各stock_idのために、二回ごとPRODUCT_IDです:

のproduct_idが注文したこの時点で、テーブル内の行の例(VARCHARは、醜いが、必要に応じて)、書式設定を言い訳します。 3番目の在庫を同様の方法で作成したい場合は、前回と全く同じクエリで「3 AS在庫ID」を代入すると、最初の商品行にこのエラーが表示されます:

"重複エントリ" 0032705090062-3 'キー2について

突然、product_id 0032705090062とstock_id 3の組み合わせは、株価1と2と同じように一意ではありますが、一意性制約に違反していると思われます。

はFunnily十分な、単一の行が作成されますので、新しい行があります:

21563 0032705090062 3 5 

...しかし、それは私が挿入しようとしている10 000+のうちの1つにすぎません。

私はここで何が欠けていますか?最初のSELECT ... INSERT INTOは機能しますが、2番目のSELECTは機能しないのはなぜですか?

答えて

2

それは

22  0032705090062 1  1 
21  0032705090345 1  6 

をつかむ初めて、あなたは再びそれを実行したとき、それは意志が

10783 0032705090062 2  13 
10784 0032705090345 2  0 

を挿入するようにするには、あなたに挿入している同じテーブルから選択します:

GET  22  0032705090062 1  1 
INSERT 21563 0032705090062 3  5 
GET  10783 0032705090062 2  13 
INSERT   0032705090062 3 <-- oops, already exists 

WHERE stock_id = 1を選択してください。

+0

ありがとうございました!私はそれを認識しませんでした。今すぐ動作します。 –

1

シンプル:今20.000行(いない10.000、あなたが思っているように)があるため、あなたの2番目の挿入は失敗し

INSERT INTO `products_quantity` (product_id, stock_id, quantity) 
    SELECT 
     product_id, 
     3 AS stock_id, 
     FLOOR(-1 + (RAND() * 15)) AS random_quantity 
    FROM 
     products_quantity; 
    WHERE 
     stock_id = 1 /* !!!!! */ 

。 where句を追加すると、10.000だけが挿入されます。

関連する問題