none
リレーションをもつテーブルで関連する情報を一括削除するには RRS feed

  • 質問

  • 関連をもつ2つのテーブルを用意し、

    主テーブルの情報を削除すると、

    それに関連する従テーブルの情報も同時に削除される、

    という方法を探して、以下のテストを行いました。

     

    ひらがな 50音を行とその要素に分けたテーブルを以下のように用意しました。
    columns テーブルの id は chars テーブルで column_id として使われています。

     

    コード ブロック

    columns
    ------------------------------------------------
    id      INT             NOT NULL PRIMARYKEY <-------+
    name    VARCHAR(50)     NOT NULL                    |   
    ------------------------------------------------    |
                                                        |
    chars                                               |
    ------------------------------------------------    |
    id          INT             NOT NULL PRIMARYKEY     |
    column_id   INT             NOT NULL ---------------+ FOREIGNKEY
    name        VARCHAR(50)     NOT NULL
    ------------------------------------------------

     

    具体的にはデータを以下のように格納させました。

     

    コード ブロック

    columns
    -------------
    id      name
    -------------
     1      あ
     2      か
     3      さ
     4      た
     5      な
     6      は
     7      ま
     8      や
     9      ら
    10      わ
    -------------

    chars
    ---------------------
    id  column_id   name
    ---------------------
     1   1          あ
     2   1          い
     3   1          う
     :   :          :
     :   :          :
     :   :          :
    44  10          わ

    ---------------------

     

    そして Form 上に

    columnsDataTable をドラッグして作った DataGridView と

    charsDataTable をドラッグして作った DataGridView を用意しました。

    columns の選択を変えると chars の表示も切り替えられるように、

    関連性を保たせています。

     

    このような状態で、
    ある行を columns から削除すると、
    それに関連する chars の要素も同時に消せないか、
    と期待してやってみました。

     

    例えば、「あ行 (id=1)」を columns で消すと、あ行に含まれる「あいうえお」
    のデータ (column_id=1) が chars から一緒に消される、ということを期待し
    ました。

     

    多分、そんな面倒見の良いことはないだろう、という予想通り、以下の例外を
    発して中止されました。


    ここで、質問ですが、上記の期待通り、関連するデータをリレーションに従って、
    一括で削除してくれる手段は .net にあるのでしょうか?

     

    CakePHP という Web のフレームワークでは可能です。

     

    コード ブロック

    $id = 1;

    $Column->delete($id);

     

    とするだけです。

    columns から id = 1 を delete する、と命令するだけです。

    フレームワークが chars の column_id = 1 のデータを勝手に消してくれます。

     

    ご存知の方、お教え願えませんか。


     

    コード ブロック

    System.Data.SqlClient.SqlException はハンドルされませんでした。
      Message="DELETE ステートメントは REFERENCE 制約 \"FK_chars_columns\" と競合しています。競合が発生したのは、データベース \"6E6882DDDE6704576F3E480A95840CD0_L SETTINGS\\APPLICATION DATA\\TEMPORARY PROJECTS\\RELATIONALDELETE\\BIN\\DEBUG\\SYLLABARY.MDF\"、テーブル \"dbo.chars\", column 'column_id' です。\r\nステートメントは終了されました。"
      Source=".Net SqlClient Data Provider"
      ErrorCode=-2146232060
      Class=16
      LineNumber=1
      Number=547
      Procedure=""
      Server="
    \\\\.\\pipe\\50D9760A-68D9-46\\tsql\\query"
      State=0
      StackTrace:
           場所 RelationalDelete.syllabaryDataSetTableAdapters.TableAdapterManager.UpdateAll(syllabaryDataSet dataSet) 場所 C:\Documents and Settings\custar\Local Settings\Application Data\Temporary Projects\RelationalDelete\syllabaryDataSet.Designer.cs:行 1923
           場所 RelationalDelete.Form1.columnsBindingNavigatorSaveItem_Click(Object sender, EventArgs e) 場所 C:\Documents and Settings\custar\Local Settings\Application Data\Temporary Projects\RelationalDelete\Form1.cs:行 23
           場所 System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
           場所 System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
           場所 System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
           場所 System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
           場所 System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
           場所 System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
           場所 System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
           場所 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           場所 System.Windows.Forms.Control.WndProc(Message& m)
           場所 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
           場所 System.Windows.Forms.ToolStrip.WndProc(Message& m)
           場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           場所 System.Windows.Forms.Application.Run(Form mainForm)
           場所 RelationalDelete.Program.Main() 場所 C:\Documents and Settings\custar\Local Settings\Application Data\Temporary Projects\RelationalDelete\Program.cs:行 18
           場所 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           場所 System.Threading.ThreadHelper.ThreadStart()
      InnerException:

     

     

    2007年12月20日 17:23

回答

すべての返信