|
以前検証のため作った SqlDataAdapter の場合の例ですが、ODP.NET でも多分 似たような形になると思いますので、参考に張っておきます。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient;
namespace SqlDataAdapterTest { public partial class Form1 : Form { private void Form1_Load(object sender, EventArgs e) {
}
private DataSet dataset; private SqlDataAdapter adapter; private string connString; private SqlConnection connection; private BindingSource bindingSource;
public Form1() { InitializeComponent();
connString = Properties.Settings.Default.MyDB; connection = new SqlConnection(connString); adapter = CreateAdapter(connection); dataset = CreateDataSet(adapter); bindingSource = new BindingSource(); bindingSource.DataMember = "Cards"; bindingSource.DataSource = dataset; bindingNavigator1.BindingSource = bindingSource;
// AutoGenerateColumns が True の場合は、データソースの各列に対して DataPropertyName が // その列名になっている列が既に存在すればその列にバインドし、存在しなければ新しく列が作 // 成されます。AutoGenerateColumns が False の場合も、データソースの各列に対して // DataPropertyName がその列名になっている列が既に存在すればその列にバインドしますが、 // 存在しなかった場合には新しい列を作成しません。 dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = bindingSource; }
public SqlDataAdapter CreateAdapter(SqlConnection connection) { // SqlDataAdapter の作成。 adapter = new SqlDataAdapter();
string query = "SELECT ID, CardYear, KindOfCard, SendMonth, SendDay, RecieveMonth, ReceiveDay, CardMemo FROM Cards"; SqlCommand command = new SqlCommand(query, connection); command.CommandType = CommandType.Text; adapter.SelectCommand = command;
query = "INSERT INTO Cards (ID, CardYear, KindOfCard, SendMonth, SendDay, RecieveMonth, ReceiveDay, CardMemo) " + "VALUES (@ID, @CardYear, @KindOfCard, @SendMonth, @SendDay, @RecieveMonth, @ReceiveDay, @CardMemo)"; command = new SqlCommand(query, connection); command.Parameters.Add("@ID", SqlDbType.Int, 0, "ID"); command.Parameters.Add("@CardYear", SqlDbType.Int, 0, "CardYear"); command.Parameters.Add("@KindOfCard", SqlDbType.Int, 0, "KindOfCard"); command.Parameters.Add("@SendMonth", SqlDbType.Int, 0, "SendMonth"); command.Parameters.Add("@SendDay", SqlDbType.Int, 0, "SendDay"); command.Parameters.Add("@RecieveMonth", SqlDbType.Int, 0, "RecieveMonth"); command.Parameters.Add("@ReceiveDay", SqlDbType.Int, 0, "ReceiveDay"); // MSDN ライブラリには「可変長データ型では、Size は、サーバーに送 // 信するデータの最大量を示します。」とあるが、0 の場合は制限しな // い。0 以外の数字を入れると制限する。例えば以下のように 5 にする // と 5 文字に制限される。5 文字を超えて入力してもエラーは出ない。 // DataSet には入力しただけ文字列が入るので、表示と DB の内容が // 異なってしまう。やはり制限するならもっと前の段階の TextBox への // 入力時にすべき。 command.Parameters.Add("@CardMemo", SqlDbType.NVarChar, 5, "CardMemo"); adapter.InsertCommand = command;
query = "UPDATE Cards " + "SET ID = @ID, CardYear = @CardYear, KindOfCard = @KindOfCard, SendMonth = @SendMonth, SendDay = @SendDay, " + "RecieveMonth = @RecieveMonth, ReceiveDay = @ReceiveDay, CardMemo = @CardMemo " + "WHERE (([ID] = @Original_ID) AND ([CardYear] = @Original_CardYear) AND ([KindOfCard] = @Original_KindOfCard))"; command = new SqlCommand(query, connection); command.Parameters.Add("@ID", SqlDbType.Int, 0, "ID"); command.Parameters.Add("@CardYear", SqlDbType.Int, 0, "CardYear"); command.Parameters.Add("@KindOfCard", SqlDbType.Int, 0, "KindOfCard"); command.Parameters.Add("@SendMonth", SqlDbType.Int, 0, "SendMonth"); command.Parameters.Add("@SendDay", SqlDbType.Int, 0, "SendDay"); command.Parameters.Add("@RecieveMonth", SqlDbType.Int, 0, "RecieveMonth"); command.Parameters.Add("@ReceiveDay", SqlDbType.Int, 0, "ReceiveDay"); command.Parameters.Add("@CardMemo", SqlDbType.NVarChar, 5, "CardMemo"); SqlParameter parameter = command.Parameters.Add("@Original_ID", SqlDbType.Int, 0, "ID"); parameter.SourceVersion = DataRowVersion.Original; parameter = command.Parameters.Add("@Original_CardYear", SqlDbType.Int, 0, "CardYear"); parameter.SourceVersion = DataRowVersion.Original; parameter = command.Parameters.Add("@Original_KindOfCard", SqlDbType.Int, 0, "KindOfCard"); parameter.SourceVersion = DataRowVersion.Original; adapter.UpdateCommand = command;
query = "DELETE FROM Cards WHERE " + "((ID = @Original_ID) AND (CardYear = @Original_CardYear) AND (KindOfCard = @Original_KindOfCard))"; command = new SqlCommand(query, connection); parameter = command.Parameters.Add("@Original_ID", SqlDbType.Int, 0, "ID"); parameter.SourceVersion = DataRowVersion.Original; parameter = command.Parameters.Add("@Original_CardYear", SqlDbType.Int, 0, "CardYear"); parameter.SourceVersion = DataRowVersion.Original; parameter = command.Parameters.Add("@Original_KindOfCard", SqlDbType.Int, 0, "KindOfCard"); parameter.SourceVersion = DataRowVersion.Original; adapter.DeleteCommand = command;
return adapter; }
public DataSet CreateDataSet(SqlDataAdapter adapter) { // DataSet の作成。 DataSet ds = new DataSet(); adapter.Fill(ds, "Cards"); DataTable table = ds.Tables["Cards"];
// 主キーは以下のようにしないと設定されない(自動的には設定されない)。 // 制約違反例外をスローするのは DataSet/DataTable でなく、DataGridView になる。その例外を処置するには // DataGridView.DataError イベントを利用する。 // DataGridView に制約情報を渡しているのは BindingSource なのか?・・・と思ったがそうではない。 table.PrimaryKey = new DataColumn[] { table.Columns["ID"], table.Columns["CardYear"], table.Columns["KindOfCard"] }; //DataColumn[] columns = table.PrimaryKey; //int num = columns.Length;
// 制約を DataTable に追加するには DbDataAdapter.FillSchema メソッドというのもある。
return ds; }
private void toolStripButtonSaveItem_Click(object sender, EventArgs e) { try { this.Validate(); this.bindingSource.EndEdit(); this.adapter.Update(dataset, "Cards"); MessageBox.Show("Update successful"); } catch (System.Exception ex) { MessageBox.Show("Update failed", ex.Message); } }
} }
|