5

アクティブなテーブルと非アクティブなテーブルの 2 つのテーブルがあります。行をアクティブ テーブルから非アクティブ テーブルに移動したいと考えています。私の最初の考えは

insert into inactive select * from active where ...
delete from active active where ...

ただし、約 .42 秒後、更新によって where 句の選択内容が変更されると、行が削除/複製されることに気付きました。

この場合、簡単に防ぐことができますが、できない場合はどうすればよいですか?

編集:回答から、これを行うための簡単で簡単な方法はないようです。これには本当に驚きました。持っているとかなりのメリットがあると思います。

4

8 に答える 8

8

ステータスフラグはあなたの友達です。

UPDATE old_data SET move="MARKED";
INSERT INTO somewhere... SELECT where move="MARKED";
DELETE FROM old_data WHERE move="MARKED";

自動コミットをオフにしてこれを行うと、いたるところでロックが取得されます。

ロックを少し減らしたい場合は、各ステップの後にコミットできます。

于 2008-11-18T21:01:46.297 に答える
4

(少なくとも MS SQL では) トランザクションとロックのヒントを使用できます。

begin tran

insert into inactive
select * from active with (updlock)
where ...

delete from active
where ...

commit tran

ロック ヒント (updlock) がないと、誰かが削除中のレコードを変更すると、デッドロックが発生する可能性があります。

于 2008-11-18T21:03:26.137 に答える
4

データベースは OUTPUT 句をサポートしていますか? そうすれば、これはあなたにとって完璧で簡単に実行できるソリューションになる可能性がありますね。

http://msdn.microsoft.com/en-us/library/ms177564.aspx

delete active with (readpast)
output DELETED.*
into inactive
where ...
于 2008-11-19T14:38:32.793 に答える
1

行を悲観的にロックできる場合、つまり、行を読み取って非アクティブなテーブルにコピーできる場合、誰もあなたの下から行を変更することはできません。

行をロックする方法はデータベースのブランドによって異なりますが、質問ではそれを指定していません。

于 2008-11-18T21:04:20.613 に答える
1

ローカル テーブル var を宣言してそこに値を入力し、それらを非アクティブ テーブルに挿入してから、ローカル リストにあるアクティブ テーブルから行を削除します。

ただし、トランザクションのアイデアも同様に機能します。

于 2008-11-18T21:05:08.053 に答える
1

次のような一意のID列を使用します

delete from active where rowid in (select rowid in inactive)

また

delete from active as a 
where exists (select * 
              from inactive 
              where pkfld1=a.pkfld1 
              and pkfld2=a.pkfld2)

また、このプロセスをトランザクションでラップすることを忘れないでください。

幸運を。

于 2008-11-18T21:06:16.473 に答える
0

「IsActive」の列ではなく、2つのテーブルがあるのはなぜですか。

于 2008-11-18T21:43:53.543 に答える
0

これは、where 句を保持する方法です。

DECLARE @MyTable TABLE
(
  TheKey int PRIMARY KEY
)
--
INSERT INTO @MyTable(TheKey)
SELECT TheKey FROM SourceTable WHERE rows I want
--
INSERT INTO Inactive(fieldlist)
SELECT fieldlist
FROM Active
WHERE TheKey IN (SELECT TheKey FROM @MyTable)
--
DELETE
FROM Active
WHERE TheKey IN (SELECT TheKey FROM @MyTable)

これ以上の強度が必要な場合は、ロック (トランザクション中の変更をブロックする) を検討する必要があります。

于 2008-11-18T21:14:37.470 に答える