0

許可されたユーザーがコンテンツを追加できるWebサイトをホストしています。コンテンツはWebページのブロック内に配置されます。許可されたユーザーは、新しいブロックを作成し、特定の順序でブロックを配置できます。ブロックの順序と内容はデータベース内に保存されます。

新しいブロックが作成されると、次の2つのMySQLクエリが実行されます。

データベース内のブロックの注文番号は、次のクエリで更新されます。

UPDATE `Block`
SET `block_order` = `block_order` + 1
WHERE `tab_nr` = $tab_nr
AND `block_order` > $nr;

次のクエリを実行すると、新しいブロックが追加されます。

INSERT INTO `Block`
  (`id`, `tab_nr`, `block_order`, `html`, `created`)
VALUES
  (NULL, $tab_nr, $nr + 1, '$html', CURRENT_TIMESTAMP);

これらのクエリの問題は、2番目のクエリで何が起こっても、最初のクエリが実行されることです。2番目のクエリが失敗した場合(理由が何であれ)、他のブロックの注文番号は最初のクエリの実行によって変更されたままです。このようにして、ブロックの注文番号がめちゃくちゃになりました。

私が必要としているのは、データベースに新しいブロックを追加し、同じ番号のブロックがある場合にのみ、他のブロックの注文番号を更新する単一のクエリです。ただし、問題は、必要なすべてを実行するクエリが見つからなかったことです。たとえば、「ON DUPLICATE KEY UPDATE」は、新しい挿入と競合する行のみを更新しますが、私の場合、他の行も更新する必要があります。上記の問題を取り除くクエリの提案はありますか?

4

2 に答える 2

2

トランザクションデータベースクエリを見てください。これは、あなたがやろうとしていることを達成するための適切な方法です。

于 2012-07-31T15:36:52.043 に答える
0

Mattがコメントで述べたように、トランザクションクエリを使用する必要があります。このようなものが役立つ場合があります。

START TRANSACTION;

UPDATE Block
SET block_order = block_order + 1
WHERE tab_nr = $tab_nr
AND block_order > $nr;

INSERT INTO Block
  (id, tab_nr, block_order, html, created)
VALUES
  (NULL, $tab_nr, $nr + 1, '$html', CURRENT_TIMESTAMP);

COMMIT;

したがって、最初のクエリが失敗した場合でも、トランザクション全体がロールバックされ、混乱を回避できます。

于 2012-07-31T15:39:43.580 に答える