- PR -

[ASP.NET ADO.NET]パラメータクエリでの更新について

投稿者投稿内容
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-01 22:30
 そして、sSql
引用:

sSQL = sSQL & " SET CODE=@CODE_New


を見るに少なくとも@CODE_Newには@CODE_Orgとは違う新しい値が入るはずです。

pc.Add("@CODE_New", SqlDbType.Char, 4, "CODE").Value = xxxxx;

としてxxxxxに新しい値を設定してみてください。

(ちなみになんだか知らないが、こちらの環境ではValueがIntelliSenseコード補完に出てこない、
というクソッタレな事態が生じています。もしそちらで同じ現象が起こっていたら、
マリアナ海溝より深く同情申し上げます。)

[ メッセージ編集済み 編集者: lalupin4 編集日時 2005-12-01 22:56 ]
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-01 22:55
引用:

また、書籍を参考に記述した下記コードについて
実際どういったことが行われて(起こって)いるのか、お教えいただけませんでしょうか?
pc.Add("@CODE_Refresh", SqlDbType.Char, 4, "CODE")
cmd.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord
ヘルプでは少しわかりづらかったです。


http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemdataupdaterowsourceclasstopic.asp
なるほど、ひどいドキュメンテーションです。

1行目:
パラメータは@CODE_Refreshという名前であり、固定長文字列、4文字として、DataTableのCODE列にマップされる。
2行目:
DataTableはデータベースを最初に更新した値でDataTableのCODE列を上書きする。

という感じでしょうか。

参照:
Scappa, David
「さらに進んだ更新のシナリオ」
『プログラミング Microsoft ADO.NET』
2002年 日経BPソフトプレス pp481-539

[ メッセージ編集済み 編集者: lalupin4 編集日時 2005-12-01 22:57 ]
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-01 23:05
 おっと、最後のSelect文を取り込みたいなら

sSQLを

sSQL = sSQL & @CODE_Refresh = CODE where

として、

cmd.UpdatedRowSource = UpdateRowSource.OutPutParameter
または
cmd.UpdatedRowSource = UpdateRowSource.Both
としなければならないかもしれません。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-01 23:12
 あれ、そうすると当初の目的と違ってくるな。

まあいいや。ここまでの説明でどこまでわかったか教えてもらえれば、以降の説明を考えられます。
Qoo
会議室デビュー日: 2005/12/01
投稿数: 4
投稿日時: 2005-12-02 13:42
詳しいご説明ありがとうございます。
パラメータクエリ等、全てにおいて理解ができていませんでした。

初歩的な質問で申し訳ないのですが、
教えてくださった
-----------
pc.Add("@CODE_New", SqlDbType.Char, 4, "CODE").Value = xxxxx;
としてxxxxxに新しい値を設定してみてください。
-----------
これで新しい値をセットするということですが、これは


-----------
Dim row As DataRow
Dim TBL As DataTable = DS.Tables("MSTTBL")
row = TBL.Rows.Find(txtCD.Text)
row("KANA") = txtKana.Text (画面の値です)
row("NAME") = txtName.Text
row("JYUSYO") = txtJyusyo.Text
row("TEL") = txtTel.Text
-----------
このようにすることとは、意味(使用法?)が全く違っているんでしょうか?

lalupin4様がご覧になっているのと同じ書籍を参考にしているのですが
Commandオブジェクトの利用(p419)とDataAdapterオブジェクトの利用(p431)とで
混乱しています。

p433のコードのUPDATEのWHERE句の部分を主キー列とTIMESTAMP列にしたいと思い、
p483のバッチクエリを使用して新しいTIMESTAMP列の値を取得したいと考えた次第です。
簡単なマスタメンテを作成しようとしているのですが、通常はこのような手法は
取らないのでしょうか?

lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-03 11:42
引用:

Commandオブジェクトの利用(p419)とDataAdapterオブジェクトの利用(p431)とで
混乱しています。


/// <summary>
/// 一番簡単なCommandの使用法。
/// </summary>
/// <param name="connection">コネクション。</param>
public static void UpdateByCommand(SqlConnection connection)
{
  //今回はデータベースにクエリを投げてみようと思う。
  SqlCommand command = new SqlCommand();

  //値はこんなカンジで
  command.Parameters.Add("@0", SqlDbType.VarChar).Value = "カナ";
  command.Parameters.Add("@1", SqlDbType.VarChar).Value = "名前";
  command.Parameters.Add("@2", SqlDbType.VarChar).Value = "住所";
  command.Parameters.Add("@3", SqlDbType.VarChar).Value = "電話";
  command.Parameters.Add("@4", SqlDbType.DateTime).Value = DateTime.Now;

  command.Parameters.Add("@5", SqlDbType.Int).Value = 1;

  //対象は大体こうで
  command.CommandText = "update MSTTBL set "
    + "KANA = @0, "
    + "NAME = @1, "
    + "JYUSHO = @2, "
    + "TEL = @3, "
    + "TIMESTAMP = @4"
    + " where "
    + "CODE = @5";

  //むーすんで
  command.Connection = connection;
  //ひーらいーて
  command.Connection.Open();

  //てーをーうって(クエリではなく、リターンがないのだと思うが…)
  command.ExecuteNonQuery();

  //むーすんで
  command.Connection.Close();
}
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-03 13:19
/// <summary>
/// Adapterを使った更新。
/// </summary>
/// <param name="original">変更前のDataSet。</param>
/// <param name="connection">コネクション。</param>
/// <returns>変更されたDataSet。</returns>
public static DataSet UpdateByAdapter(DataSet original, SqlConnection connection)
{
  //引数は直接変更しないのがグッド・プラクティスなんだそうで。
  DataSet updated = original.Copy();

  //DataSetへの変更をデータベースに反映させようと思いたった土曜の午後。
  SqlDataAdapter adapter = new SqlDataAdapter();

  //Updateするときはこのコマンドをつかう。
  SqlCommand command = new SqlCommand();

  //DataSetの値の変更をパラメータのValueとします。
  //DataRowのどのバージョンの値を使用するかを指定します。
  SqlParameter parameter = null;
  parameter = command.Parameters.Add("@0", SqlDbType.VarChar, 10, "KANA");
  parameter.SourceVersion = DataRowVersion.Current;
  parameter = command.Parameters.Add("@1", SqlDbType.VarChar, 10, "NAME");
  parameter.SourceVersion = DataRowVersion.Current;
  parameter = command.Parameters.Add("@2", SqlDbType.VarChar, 100, "JYUSHO");
  parameter.SourceVersion = DataRowVersion.Current;
  parameter = command.Parameters.Add("@3", SqlDbType.VarChar, 15, "TEL");
  parameter.SourceVersion = DataRowVersion.Current;
  parameter = command.Parameters.Add("@4", SqlDbType.DateTime, 8, "TIMESTAMP");
  parameter.SourceVersion = DataRowVersion.Current;
  parameter = command.Parameters.Add("@5", SqlDbType.Int, 1, "CODE");
  parameter.SourceVersion = DataRowVersion.Original;

  //SQL
  command.CommandText = "update MSTTBL set "
    + "KANA = @0, "
    + "NAME = @1, "
    + "JYUSHO = @2, "
    + "TEL = @3"
    + "TIMESTAMP = @4"
    + " where "
    + "CODE = @5;";

  //接続
  command.Connection = connection;

  //では後ほど。
  adapter.UpdateCommand = command;


  //行の値を変更する。
  DataTable table = updated.Tables["MSTTBL"];
  DataRow row = table.Rows.Find(1);

  row.BeginEdit();
  //Propose値に新しい値を入れます。
  row["KANA"] = "new KANA";
  row["NAME"] = "new NAME";
  row["JUSHO"] = "new JYUSHO";
  row["TEL"] = "new TEL";
  row["TIMESTAMP"] = DateTime.Now
  row["CODE"] = 2; //Original値を使用するのでこの値は使用されません。
  //Current値がPropose値で上書きされます。
  row.EndEdit();

  //お前は引数を変更すんのか。なんて奴だ。
  adapter.Update(updated);

  //もういい。帰れ。
  return updated;
}
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2005-12-03 13:31
引用:

簡単なマスタメンテを作成しようとしているのですが、通常はこのような手法は
取らないのでしょうか?


 見てのとおりAdapterはCommandの少なくとも3倍は複雑です。
この師走の時期にAdapterでCRUD(Create, Read, Update, Delete)完全対応させようとか
思ったら無事に年は越せますまい。

 私なら、同じ3倍ならCommandを使用するCRUDメソッドを3つでも4つでも作って、
独立に制御するほうを選びます。

 私が唯一Adapterの使用を真っ先に検討する状況はJoinするSelect文をAdapter.Fill()
でDataSetに収める場合だけです。

スキルアップ/キャリアアップ(JOB@IT)