none
TableAdapterについて RRS feed

  • 質問

  • こんにちは。

    TableAdapterについて、ヘルプなどを参考にしながらテストをしています。
    DBはSqlsrever2005を使用しています。

    テストにと思い、「データ」→「データソースの追加」から、ひとつのテーブルを選択しました。
    データソースエクスプローラーのDataTable(?言葉が間違っていたらすいません)の右側の下向き矢印をクリックし、詳細を選択して、テーブルをフォームへドラッグして単票形式でフォームに表示をしてあります。

    実行を行うとデータも表示され、移動ボタンにて、データの移動も可能です。
    しかし、フォームのいずれかの項目を変更して、保存ボタンをクリックすると以下のようなメッセージが出てしまいます。

    {"パラメータ化クエリ '(@pt_code varchar(10),@pt_name varchar(40),@pt_kana varchar(40),' に必要なパラメータ '@IsNull_pt_birthday' が指定されていません。"}

    主キーはpt_codeとなっています。(SQLServer management sdudioで該当のテーブルを開き、PKとなっていることを確認。)
    自動的に生成されたものなので、一体どこを直せばよいか見当も付きません。

    どうか、アドバイスをお願いします。
    2007年6月10日 6:35

回答

  • ご回答ありがとうございます。

     

    必要な情報を提示せず申し訳ありません。

     

    該当のデータは、Int型をバインドしてあります。

     

    ご提示いただきましたリンクを拝見させていただきました。

    CausesValidationをFalseに指定する方法、ならびにフォームのDesignerの該当テキストボックスの記述の部分に以下を追加することの両方を試したところ、どちらも可能でした。

    しかし、UpdateCommandにて該当のテキストボックスが「””」(データがない場合)にデータの更新でNull値をわたすSQL文がわからなかったので、以下の記述を採用してあります。

    System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged.string.Empty));

     

    しかし、上記の記述がデータソースをそのままフォームに貼り付けをした場合には自動的に記述されるようになっていると非常にありがたいですね。

     

    えむナウ様、trapemiya様、本当にありがとうございました。

    また、困ったときはどうかよろしくお願いします。

    2007年6月16日 21:34

すべての返信

  • 実際に実験したわけではないのではずしているかもしれませんが、

    TableAdapterには禁句があります。

    テーブルの中にIsNull_pt_birthdayという項目があるなら、

    IsNullではない先頭文字にSQLServer側で変更してみて、

    再度データソースから作成しなおしてください。

    データセットデザイナのテーブル右クリック-構成でもいいかもしれません。

     

    テーブルの Original_xxx という項目は更新できない

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=953607&SiteID=7

    2007年6月10日 7:20
  • ご回答ありがとうございます。

     

     えムナウ さんからの引用

    テーブルの中にIsNull_pt_birthdayという項目があるなら、

    コレについてですが、テーブルには「pt_birthday」というフィールドがあり(Null値を許可しております。)ますが、「IsNull_pt_birthday」というフィールドはありません。

     

     えムナウ さんからの引用

    テーブルの Original_xxx という項目は更新できない

    http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=953607&SiteID=7

    こちらも読ませていただきました。

    このような現象があるのですね。

     

    代用案として、IsNull_pt_birthdayを省いてしまうということは問題ないのでしょうか。

    問題のSQL文をいかに載せます。

     

    UPDATE         t_patient
    SET                pt_code = @pt_code, pt_name = @pt_name, pt_kana = @pt_kana,
                          pt_sex = @pt_sex, pt_birthday = @pt_birthday,
                          pt_addresscode = @pt_addresscode, pt_tel = @pt_tel, pt_keitai = @pt_keitai,
                          pt_fax = @pt_fax
    WHERE           (pt_code = @Original_pt_code) AND (pt_name = @Original_pt_name) AND
                          (pt_kana = @Original_pt_kana) AND (pt_sex = @Original_pt_sex) AND
                          (@IsNull_pt_birthday = 1 AND pt_birthday IS NULL OR
                          pt_birthday = @Original_pt_birthday) AND (@IsNull_pt_addresscode = 1 AND
                          pt_addresscode IS NULL OR
                          pt_addresscode = @Original_pt_addresscode) AND (@IsNull_pt_tel = 1 AND
                          pt_tel IS NULL OR
                          pt_tel = @Original_pt_tel) AND (@IsNull_pt_keitai = 1 AND pt_keitai IS NULL OR
                          pt_keitai = @Original_pt_keitai) AND (@IsNull_pt_fax = 1 AND pt_fax IS NULL OR
                          pt_fax = @Original_pt_fax)

     

    2007年6月10日 9:20
  • オプティミスティック同時実行制御がらみの機構ですね。

    http://msdn2.microsoft.com/ja-jp/library/system.data.sqlclient.sqlparameter.sourcecolumnnullmapping(VS.80).aspx

     

    とりあえず回避するにはDataSetデザイナでデータセットを右クリックして構成を選び、

    TableAdapter構成ウィザードで詳細オプションを選択し、オプティミスティック同時実行制御をOffに、

    するとUPDATEのSQL文もすっきりしてこの問題は発生しなくなります。

     

    オプティミスティック同時実行制御は同じテーブルの更新を複数の場所からおこる時に、

    読み込んだときの情報から変わっていたら更新しないようにする制御なので、

    テスト目的とかでは使う必要はないでしょう。

     

    2007年6月10日 10:23
  • おはようございます。

    教えて頂いた方法で、保存することは可能になりました。

    しかし、最終的には複数の人間による使用を考えており、同時制御ができないと困る事態も想定されるので、同時実効制御については実装したいと思っております。

    今回、オプティミスティック同時実効制御をoffにしたのですが、Accessのときなどは実際に保存する段階で、DBを確認して保存をするという段階を踏んでいたのですが、この機能はこれを自動で作成をしてくれるというものなのですよね。

    これから、IsNull_pt_codeのあたりを削除したもので、テストをしてみようと思っています。(該当のフィールドはNull値を許可してあります。)
    又、結果を報告したいと思いますので、しばらくお時間を下さい。
    2007年6月15日 0:02
  • SQL serverですとTIMESTAMP型が使えますので、これを使って同時実行制御をかけると良いです。なので、オプティミスティック同時実効制御はoffでかまいません。
    2007年6月15日 1:25
    モデレータ
  • ご回答ありがとうございます。

    早速、どのように使用できるかと調べてみたのものの、よくわからなかったので、まずオプティミスティック同時実行制御のチェックをはずし、該当するテーブルにTimeStamp型のフィールドを追加しました。

    次に、TableAdapterのUpdateCommandを以下のようにしてみたのですが、いったんフォームにデータを読み込み、その状態での変更はデータベースに反映はされるのですが、SQLServer Management Studioを使って、いったんデータを読み込んだ後に、データの修正を起こったレコードに対して、フォーム上でも変更を行い、バインディングナビゲーター(でよろしいでしょうか。)の保存ボタンをクリックしたところ、「同時実行違反」というエラーが出ます。

    UPDATE         t_patient
    SET                pt_code = @pt_code, pt_name = @pt_name, pt_kana = @pt_kana,
                          pt_sex = @pt_sex, pt_birthday = @pt_birthday,
                          pt_addresscode = @pt_addresscode, pt_tel = @pt_tel, pt_keitai = @pt_keitai,
                          pt_fax = @pt_fax
    WHERE           (pt_code = @Original_pt_code) AND (pt_timestamp = @Original_pt_timestamp)

    TimeStampを使用する制御はどのように行えばよいのでしょうか。
    どうか、よろしくお願いします。
    2007年6月16日 7:03
  •  TI-cb400s さんからの引用

    SQLServer Management Studioを使って、いったんデータを読み込んだ後に、データの修正を起こったレコードに対して、フォーム上でも変更を行い、バインディングナビゲーター(でよろしいでしょうか。)の保存ボタンをクリックしたところ、「同時実行違反」というエラーが出ます。

     

    その動作は正常です。TIMESTAMP型というのは8バイトのバイナリです。レコードが更新される度にその値が自動で更新されます。TIMESTAMP値を使用して、同時実行制御は次のように行います。

    データを読み込んだ時のTIMESTAMP値をしまっておき、その値が変わってないことを期待して(つまり、where条件にpt_timestamp = @Original_pt_timestampを付加)更新を行った時、更新に成功すれば自分がデータを読み込んでからそのレコードは変更されていないことになりますし、更新に失敗すればTIMESTAMP値が変わっているということですから、誰かがそのレコードを変更したことになります。これが同時実行制御です。

    2007年6月16日 9:09
    モデレータ
  • ご回答ありがとうございます。

     

    Try Catch構文を利用して、エラーとなる場合にSubから抜けるようにして、対処することができました。

     

    しかし、まだひとつ疑問があるのですが、NULL値を許容してあるフィールドで、すでにデータが入っているものを削除して保存をしようと試みると、データバインドされているオブジェクト(表現が間違っていたら申し訳ありません。)、たとえば、電話番号が入るはずのテキストボックスなどから、フォーカスを移動することができず、データを変更するなどすれば、保存することが可能です。

     

    この件についてはどのように対処をすればよいのでしょうか。

     

    自分なりにいろいろと調べては見たものの、どうにもわかりません。

    どうかよろしくお願いします。

    2007年6月16日 11:29
  • どのようにバインドされているのかわかりませんが、以下のcontaさんの発言が参考になるかもしれません。

     

    バインドされたTextBoxへnullの入力に関して
      http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-37893.htm

    2007年6月16日 14:21
    モデレータ
  • ご回答ありがとうございます。

     

    必要な情報を提示せず申し訳ありません。

     

    該当のデータは、Int型をバインドしてあります。

     

    ご提示いただきましたリンクを拝見させていただきました。

    CausesValidationをFalseに指定する方法、ならびにフォームのDesignerの該当テキストボックスの記述の部分に以下を追加することの両方を試したところ、どちらも可能でした。

    しかし、UpdateCommandにて該当のテキストボックスが「””」(データがない場合)にデータの更新でNull値をわたすSQL文がわからなかったので、以下の記述を採用してあります。

    System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged.string.Empty));

     

    しかし、上記の記述がデータソースをそのままフォームに貼り付けをした場合には自動的に記述されるようになっていると非常にありがたいですね。

     

    えむナウ様、trapemiya様、本当にありがとうございました。

    また、困ったときはどうかよろしくお願いします。

    2007年6月16日 21:34