7

データベースの移行中に、次の形式のデータベース テーブル制約に遭遇しました。

ALTER TABLE [dbo].[myTable]
ADD CONSTRAINT [someName] FOREIGN KEY ([id]) REFERENCES [dbo].[myTable] ([id])
ON DELETE NO ACTION
ON UPDATE NO ACTION

なぜこれを行うのでしょうか?これは、もともと Sybase データベースで行われていたもので、SQL Server 2008 R2 に変換しています。

UPDATE : はい、外部キー制約は同じテーブルと同じフィールドを参照するフィールドです。

ソースの Sybase データベースでこのクエリを実行したところ、これらのクレイジーなキーが 42 個定義されていることがわかったので、タイプミスではないようです。

SELECT sr.constrid as [Constraint ID],
       so.name as [Table],
       sc.name as [Column]
  FROM sysreferences sr
       INNER JOIN sysobjects so ON (so.id = sr.tableid)
       INNER JOIN syscolumns sc ON (sc.id = sr.tableid AND sc.colid = sr.fokey1)
 WHERE sr.tableid = sr.reftabid
   AND sr.fokey1 = sr.refkey1
   AND sr.fokey2 = 0
   AND sr.refkey2 = 0
4

4 に答える 4

2

次のように、同じテーブルに外部キーを使用するときはいつでも、階層が本で見つかる標準的な例だと思います。

create table Employees (
 EmployeeID int identity primary key,
 EmployeeName varchar(50),
 ManagerID int
 Foreign key (managerID) references Employees(EmployeeID)
)

あなたが投稿したものは、同じテーブルでこの階層関係を間違って適用しているように見えます。なぜあなたがそれをしたいのか、私にはよくわかりません。

これが役に立ったことを願っています=)

于 2012-10-18T21:59:05.387 に答える
1

サプライズ!これは完全に機能します:

create table crazy (
    ID int primary key references crazy (ID) -- This runs
);
insert into crazy select 1;  -- So does this
select * from crazy; -- Returns 1
truncate table crazy; -- Works just fine

これは間違いだったとしか思えません (タイポ? ダイアグラム内で列をドラッグする?) か、別のシステム (ORM?) をだまして特定の動作をさせるために使用されました。誰かが正当な理由を思い付くかどうか、私は非常に興味があります.

更新: @8kb が巧妙に提案したように、これは切り捨てを防止する試みであった可能性がありますが、私の例から、切り捨てでも問題なく機能することがわかります。

于 2012-10-18T21:59:56.740 に答える
0

それ自体を参照する外部キー列の影響は何もないようです。なぜデータベース エンジンがこのような無駄なことをさせてしまうのかは、まだ未解決の問題です。

ただし、誰かがこのような外部キーを作成する理由は、怠惰/不注意だと思います。SQL Server Management Studio で、(T-SQL で書き出すのではなく) GUI を使用して外部キーを作成すると、SSMS の最初の動作は、この質問とまったく同じように外部キーを作成することであることがわかりました。

  1. [オブジェクト エクスプローラー] ペインでデータベースの任意のテーブルを展開します。このテーブルを TableA と呼びます。
  2. TableA ノードの下の Keys を右クリックし、New Foreign Key... を選択します。これにより、Modify table ペインと Foreign Key Relationships ダイアログが開きます。
  3. 何も変更せず、[Foreign Key Relationships] ダイアログの [Close] ボタンをクリックするだけです。 「おっと、外部キーを追加するつもりはありませんでした。」
  4. ダイアログを閉じても、FK_TableA_TableA という名前の外部キーが生成され、主キー列がベース列と参照列の両方として選択されました。
  5. [テーブルの変更] ウィンドウを開いたまま ([外部キー リレーションシップ] ダイアログを閉じた後も)、閉じます。変更があります (作成したばかりの新しい外部キー)。これらの変更を保存します。
  6. TableA のデータベースに新しい外部キーが存在し、主キー列はそれ自体を参照します。
于 2014-06-05T16:05:47.927 に答える
0

データベースモデルのバグだと思います。

本当に変です。この構造がどのような有用な目的であるか想像できません。

データを挿入する唯一の方法は、参照整合性をチェックしないことです。これは、参照を明示的に無効にするか、何らかの一括挿入などを行うことを意味します。

于 2012-10-18T21:50:54.460 に答える