0

SQL Server 2012 で実行されたテストでDELETE FROM dbo.TableNameは、テーブル内のレコードを 1 つでも削除すると外部キー違反が発生する場合、コマンドが停止してエラーが返されることが明らかになりました。レコードは削除されません。

  • 未使用のレコードは、外部キーの関係に違反せずに削除できるレコードであるとします。

  • すべてのレコードは、null 非許容の整数 ID 列によって一意に識別できると仮定します。

  • トリガーやカスケード削除など、副作用を引き起こす可能性のある機能は無視しても安全であると想定してください。

  • テーブル、そのレコード、および関係については、それ以外はほとんど想定されていません。(例: ソリューションは、これらのパラメーター内で一般的である必要があります。)

次の形式で未使用の親レコードを削除するソリューションはありますか?

  1. 原因となったレコードのエラーを無視し、そうでないレコードに対して正常に実行される SQL は?
  2. どういうわけか検出された未使用の親レコードのセットに対してのみ DELETE を実行する SQL? (FK リレーションシップがわかっている特定のテーブルに対しては簡単に実行できます。一般的に実行するのはそれほど簡単ではありません。)
  3. 上記のソリューションと同等の機能を実行するサーバー側のコードは?

ノート:

  • C#、Python、Java、Ruby などを必要とするソリューションよりも、SQL ソリューションの方が適しています。
  • クロス RDBMS ソリューションは、RDBMS 固有のソリューションよりも推奨されます。

ソリューションが適用され、テストされた RDBMS を記載してください。

4

4 に答える 4

0

行に PK への参照がある場合、その削除は失敗しますが、続行されます。

SET NOCOUNT ON;

DECLARE @PK varchar(10);

PRINT '-------- Delete PK --------';

DECLARE delete_cursor CURSOR FOR 
SELECT PK 
FROM PKstring
ORDER BY PK;

OPEN delete_cursor

FETCH NEXT FROM delete_cursor 
INTO @PK

WHILE @@FETCH_STATUS = 0
BEGIN
    DELETE PKstring where PK = @PK 

    FETCH NEXT FROM delete_cursor 
    INTO @PK
END 
CLOSE delete_cursor;
DEALLOCATE delete_cursor;
于 2013-05-07T14:58:28.287 に答える
0

この場合、私が通常行うことは、fk 制約を無効にすることです。それが機能しない場合は、通常、制約を削除し、データを消去してから、fk を再作成します。

これを行う方法に関するクイックリンクは次のとおりです http://www.mssqltips.com/sqlservertip/1376/disable-enable-drop-and-recreate-sql-server-foreign-keys/

于 2013-05-06T19:43:51.187 に答える
0

Oracle では、次のLOG ERRORS INTOオプションを使用できます。

サンプルデータのセットアップ:

create table parent (pid integer not null primary key);
create table child 
(
  cid integer not null primary key,
  pid integer not null references parent(pid)
);

insert into parent values (1);
insert into parent values (2);
insert into parent values (3);

insert into child values (1,1);
insert into child values (2,1);
insert into child values (3,2);

すべての削除不可能な行をログに記録するテーブルを作成します。

begin
  DBMS_ERRLOG.CREATE_ERROR_LOG('PARENT', 'ERR_LOG_PARENT');
end;
/

削除を実行します。

delete from parent
log errors into err_log_parent ('delete test')
reject limit unlimited;

SQLFiddle の例: http://sqlfiddle.com/#!4/d379c/1

DBMS_ERRLOG のマニュアル: http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_errlog.htmオプション
のマニュアル: http://docs.oracle.com/cd/B28359_01/server.111/ b28286/statements_8005.htm#CEGCHDJFLOG ERRORS

于 2013-05-06T19:58:32.337 に答える
0

すべてのプラットフォームで使いたいという魔法の薬はありませんが、ほぼすべての DBMS に適応できるものを作成することはできます。はい、これは SQL サーバーの実稼働データベースで行いました。これは単一ステップのプロセスではありませんが、動的 SQL などを使用して 2 番目のステップを簡単に自動化できます。

再:

現在のレコードのすべての親テーブルを知っている必要があります。

ええ、でもそれを説明するコードを書くことはできます。INFORMATION_SCHEMA ビュー (SQL Server、MySQL) または DB の同等のビューを使用して、問題のテーブルの削除ステートメントを生成します。次に、生成したステートメントを実行します。

開始するのに適した場所は、INFORMATION_SCHEMA.TABLES、INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS、および INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE です。

于 2013-05-07T04:29:31.830 に答える