4

レコードのリストがある場合、これらのレコードを削除する前に、これらの各レコードに外部キー参照があるかどうかを確認する方法はありますか?

例として、借り手のリストと本のリストがある場合、借り手がまだ貸し出し中の本を持っている場合、その借り手をシステムから削除することはできません。(ただし、私の実際のシステムはそれよりもはるかに複雑です。より多くのテーブルがあります。)

貸出中の本を持っている借り手から削除オプションを削除したいと思います (その例で)。

外部キー参照を含むレコードを削除しようとすると、次のようなエラーが発生します。

データベース アクセスに失敗しました: 親行を削除または更新できません: 外部キー制約が失敗しました ( dbname. tablename, CONSTRAINT fkfieldidFOREIGN KEY ( fieldid) REFERENCES tablename( fieldid))

1 つの解決策は、レコードのリスト内の各レコードに、参照可能なテーブルのいずれかに外部キー参照があるかどうかを確認するクエリを作成することです。

ただし、コンテンツ管理システムのテーブルから 100 レコードのリストを表示したい場合、そのリストを表示するために 100 のサブクエリを実行する必要がある場合、明らかに非常に非効率的です!

エンド ユーザーがレコードを削除しようとすると混乱しますが、そのデータは他の場所で「使用中」であるため削除できません。混乱を避けるために、削除するオプションを削除することをお勧めします。

何をするのが最善かについてのアイデアはありますか?ありがとう。

4

2 に答える 2

1

あなたが好きかもしれないのはトランザクションです。

1) すべてのエントリを削除します。

2a) エラーが発生した場合 -> ロールバック 2b) エラーが発生しなかった場合 -> コミット

http://dev.mysql.com/doc/refman/5.0/en/commit.html

于 2010-07-01T20:55:31.283 に答える
1

これは、サブクエリまたは結合を使用して簡単に行うことができます。

すなわち。サブクエリ

SELECT B.*, (SELECT COUNT(*) FROM loans L WHERE L.book_id = b.id) loan_count
FROM books B

または参加します(複数の同時貸出を許可すると、そのような本が結果に複数回表示されることに注意してください):

SELECT B.*, L.book_id AS loaned_out_if_not_null
FROM books B
    LEFT JOIN loans L ON B.id = L.book_id

もちろん、これは GROUP BY で短縮できます。

SELECT B.id, B.name, COUNT(L.book_id) AS loan_count
FROM books B
    LEFT JOIN loans L ON B.id = L.book_id
GROUP BY B.id, B.name

データベース エンジンが CASE をサポートしている場合は、それを DISTINCT と組み合わせることで、結果に複数の行が含まれないようにすることができます (もちろん、DISTINCT にもオーバーヘッドがあります)。

SELECT DISTINCT B.*,
    CASE WHEN L.book_id IS NOT NULL THEN 1 ELSE 0 END AS loaned_out_if_one
FROM books B
    LEFT JOIN loans L ON B.id = L.book_id

これらのうち、GROUP BY バリアントを使用します。

于 2010-07-01T20:50:03.337 に答える