ユーザーにsudoを許可する

2008/08/27 11:17

ubuntuでは、su - rootは使わず、sudoでやるのが一般的らしい。
ただ最初はインストール時に作ったユーザーのみがsudoできるようで、あとで追加したユーザーがsudoできるようにする方法のまとめ。

sudoに関する設定は /etc/sudoers に記述してあるようで、インストール直後は


# /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the man page for details on how to write a sudoers file.
#

Defaults        env_reset

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL) ALL

# Uncomment to allow members of group sudo to not need a password
# (Note that later entries override this, so you might need to move
# it further down)
# %sudo ALL=NOPASSWD: ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
というようになっていて最後の、%admin ALL=(ALL) ALL という部分が「ユーザーがadminというグループに属していればsudoが使える」という設定らしい。
なので、

$ sudo usermod -G admin ユーザー
コマンドで、ユーザーをadminグループに属させることでOK。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

debianのデフォルトエディタの変更

2008/08/27 11:08

debian4.0をインストールしたとき、デフォルトエディタが/bin/nanoになっていたので、viに変更。


# update-alternatives --config editor

There are 4 alternatives which provide `editor'.

  Selection    Alternative
-----------------------------------------------
          1    /bin/ed
*+        2    /bin/nano
          3    /usr/bin/vim.tiny
          4    /usr/bin/vim.basic

Press enter to keep the default[*], or type selection number:
ここでvimを選べばOK(ここではvimがインストールしてあります)。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[リレーション#2]

2007/08/13 11:38

前回、フォーム画面を変更したので、今回はそのコードを修正していきます。

まず、ベンダー毎の商品単価テーブルのデータアダプタを用意します。
クラスのprivate変数として

// dat_item_priceのデータアダプタ
private NpgsqlDataAdapter m_da_dat_item_price = new NpgsqlDataAdapter();
// mst_vendorのデータアダプタ
private NpgsqlDataAdapter m_da_mst_vendor = new NpgsqlDataAdapter();
フォームのロードイベントで、そのデータアダプタを構築します。
// dat_item_priceのテーブルアダプタ構築
// selectコマンド
m_da_dat_item_price.SelectCommand = new NpgsqlCommand
(
       "select"
    +      " item_id"
    +     ", vendor_id"
    +     ", price"
    +     ", create_date"
    +     ", update_date"
    + " from"
    +      " dat_item_price"
    + " order by item_id, vendor_id",
    m_conn
);
// insertコマンド
m_da_dat_item_price.InsertCommand = new NpgsqlCommand
(
       "insert into dat_item_price ("
    +      " item_id"
    +     ", vendor_id"
    +     ", price"
    + " ) values ("
    +      " :item_id"
    +     ", :vendor_id"
    +     ", :price"
    + " )",
    m_conn
);
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("item_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("price"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
// updateコマンド
m_da_dat_item_price.UpdateCommand = new NpgsqlCommand
(
       "update dat_item_price set"
    +      " vendor_id=:vendor_id"
    +     ", price=:price"
    +     ", update_date=current_timestamp"
    + " where"
    +      " item_id=:item_id"
    +  " and vendor_id=:org_vendor_id",
    m_conn
);
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_id"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("price"        , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id"      , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("org_vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// deleteコマンド
m_da_dat_item_price.DeleteCommand = new NpgsqlCommand
(
       "delete from dat_item_price"
    + " where"
    +      " item_id=:item_id"
    +  " and vendor_id=:vendor_id",
    m_conn
);
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
// RowUpdatedイベントの追加
m_da_dat_item_price.RowUpdated += new NpgsqlRowUpdatedEventHandler(dat_item_priceRowUpdated);

// mst_vendorのデータアダプタ(グリッドのコンボボックス用)
// selectコマンド
m_da_mst_vendor.SelectCommand = new NpgsqlCommand
(
       "select"
    +      " vendor_id"
    +     ", vendor_name"
    +     ", create_date"
    +     ", update_date"
    + " from"
    +      " mst_vendor"
    + " order by vendor_id",
    m_conn
);
RowUpdateイベント関数を追加します。
// dat_item_priceのデータアダプタのRowUpdatedイベント
private void dat_item_priceRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
{
    if (e.Status == UpdateStatus.Continue)
    {
        if (e.StatementType == StatementType.Insert)
        {
            // create_date,update_dateを取得
            NpgsqlCommand cmd = new NpgsqlCommand("select create_date, update_date from dat_item_price where item_id="+e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
            try
            {
                NpgsqlDataReader reader = cmd.ExecuteReader();
                reader.Read();
                e.Row["create_date"] = reader["create_date"];
                e.Row["update_date"] = reader["update_date"];
            }
            catch (Exception)
            {
                throw;
            }
        }
        else if (e.StatementType == StatementType.Update)
        {
            // update_dateを取得
            NpgsqlCommand cmd = new NpgsqlCommand("select update_date from dat_item_price where item_id=" + e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
            try
            {
                NpgsqlDataReader reader = cmd.ExecuteReader();
                reader.Read();
                e.Row["update_date"] = reader["update_date"];
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}

データセットにdat_item_priceとmst_vendorを加えます。
m_da_dat_item_price.Fill(m_ds, "dat_item_price");
m_da_mst_vendor.Fill(m_ds, "mst_vendor");

ここで、今回の本題となるリレーションを定義します。
今回の画面では、上に商品マスタ、下にベンダー毎の単価のグリッドが配置されています。
上の商品マスタを1行選択したとき、下の単価データは、選択された商品の内容が表示されなければなりません。
データセット内で、mst_itemとdat_item_priceの関係をリレーションで定義してやることで、これを簡単に実現することができます。

まず、データセットのmst_itemとdat_item_priceの関連を定義します。
// リレーション作成
m_ds.Relations.Add(new DataRelation("rel_dat_item_price",
                                    m_ds.Tables["mst_item"].Columns["item_id"],
                                    m_ds.Tables["dat_item_price"].Columns["item_id"]));
rel_dat_item_priceという名前でリレーションを定義しています。
次に、グリッドやナビゲータのデータソースとなっているbind_dat_item_priceを設定します。
// bind_dat_item_priceを設定
bind_dat_item_price.DataSource = bind_mst_item;
bind_dat_item_price.DataMember = "rel_dat_item_price";
ここで注意するのは、DataSourceにはmst_itemのためのBindingSourceのbind_mst_itemを、DataMemberにはリレーションrel_dat_item_priceを設定することです。
これにより、mst_itemとdat_item_priceが関連付けされ、またグリッドも連動するようになります。

次に、grid_dat_item_priceの各列を関連付けます。
// dat_item_price
col_dat_item_id.DataPropertyName     = "item_id";
col_dat_vendor_id.DataPropertyName   = "vendor_id";
col_dat_vendor_id.DataSource         = m_ds.Tables["mst_vendor"];
col_dat_vendor_id.DisplayMember      = "vendor_name";
col_dat_vendor_id.ValueMember        = "vendor_id";
col_dat_price.DataPropertyName       = "price";
col_dat_create_date.DataPropertyName = "create_date";
col_dat_update_date.DataPropertyName = "update_date";

これで動作させると、次のような問題が発生します。
dat_item_price1.gif
データを2行追加しようとすると
dat_item_price2.gif
というエラーが発生。また、
dat_item_price3.gif
dat_item_price4.gif
というように、mst_itemとdat_item_priceが連動しません。

これは、item_idがnullとなっているため、こういった現象になります。
これまでは、1つのテーブルに対するアクセスだったため、RowUpdatedイベントでitem_idを取ってきて、データセットに入れてあげればよかったのですが、リレーションする列は何らかの一意なIDを持っておく必要があります。
これには、テーブルアダプタのm_ds.Tables["mst_item"]の、item_id列をAutoIncrementにして、自動的にIDがセットされるようにします。
今回、mst_itemのitem_idはserialにしているため、currval('mst_item_item_id_seq')でmst_item_item_id_seqの次の値を取ってきて入れてやれば一番いいんですが、シリアル値は値の増加があった同一トランザクション内でないと取得できません。
なので、mst_itemのitem_idの最大値+1をセットするのが一番しっくりくる気がします(ウィザードで生成されるコードではそうなっているようです)。
ただ、そのためにはitem_idの最大値+1を取得するSQLを発行しないといけないので、ちょっと面倒。
そこで、IDに負の数はないという前提で、AutoIncrementの初期値を-1、増加量も-1にしてしまうというやり方があります。
データ保存するまでは、item_idにマイナスの値が入りますが、各行はユニークなIDを持ちます。そして保存時のRowUpdatedイベントによって、保存された実際のIDがデータセットにセットされなおします。
// mst_itemのitem_idをAutoIncrementにする
DataColumn dc_item_id = m_ds.Tables["mst_item"].Columns["item_id"];
dc_item_id.AutoIncrement = true;
dc_item_id.AutoIncrementSeed = -1;
dc_item_id.AutoIncrementStep = -1;

これで、保存ボタンが押されたとき
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"]);
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"]);
として、データベースに書き込みたいところですが、これだと、insertのときはいいのですが、deleteのときは、リレーションしているデータがあるためmst_itemのレコードは削除できません。
では、
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"]);
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"]);
として、dat_item_priceを先に更新しようとすると、今度はinsertでエラーが出ます。

こういう場合、delete,update,insertされたレコードを別々に処理することでうまく保存することができます。
// delete
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted));
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted));
// update
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent));
// insert
update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added));
update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added));
リレーションで自分自身を指すような構造のときは、さらに工夫が必要になりそうな気がします。。。

最終的にソースは次のようになります。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;

namespace Npgsql_sample
{
    public partial class form_mst_item : Form
    {
        // メンバ変数
        // データベース接続子
        private NpgsqlConnection m_conn = new NpgsqlConnection
        (
              "Server=localhost;"
            + "Port=5432;"
            + "User Id=Npgsql_sample;"
            + "Password=hogehoge;"
            + "Database=Npgsql_sample;"
            + "Encoding=UNICODE"
        );
        // mst_itemのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_item = new NpgsqlDataAdapter();
        // mst_categoryのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
        // dat_item_priceのデータアダプタ
        private NpgsqlDataAdapter m_da_dat_item_price = new NpgsqlDataAdapter();
        // mst_vendorのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_vendor = new NpgsqlDataAdapter();
        // データセット
        private DataSet m_ds = new DataSet();

        public form_mst_item()
        {
            InitializeComponent();
        }

        private void form_mst_item_Load(object sender, EventArgs e)
        {
            // mst_itemのデータアダプタ構築
            // selectコマンド
            m_da_mst_item.SelectCommand = new NpgsqlCommand
            (
                    "select"
                +      " item_id"
                +     ", item_name"
                +     ", category_id"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_item"
                + " order by item_name",
                m_conn
            );
            // insertコマンド
            m_da_mst_item.InsertCommand = new NpgsqlCommand
            (
                   "insert into mst_item ("
                +      " item_name"
                +     ", category_id"
                + " ) values ("
                +      " :item_name"
                +     ", :category_id"
                + " )",
                m_conn
            );
            m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("item_name"  , NpgsqlTypes.NpgsqlDbType.Text   , 0, "item_name"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_mst_item.UpdateCommand = new NpgsqlCommand
            (
                   "update mst_item set"
                +      " item_name=:item_name"
                +     ", category_id=:category_id"
                +     ", update_date=current_timestamp"
                + " where"
                +      " item_id=:item_id",
                m_conn
            );
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_name"  , NpgsqlTypes.NpgsqlDbType.Text   , 0, "item_name"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_mst_item.DeleteCommand = new NpgsqlCommand
            (
                   "delete from mst_item"
                + " where"
                +      " item_id=:item_id",
                m_conn
            );
            m_da_mst_item.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdatedイベントの追加
            m_da_mst_item.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_itemRowUpdated);

            // mst_categoryのデータアダプタ構築(グリッドのコンボボックス用)
            m_da_mst_category.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " category_id"
                +     ", category_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_category"
                + " order by category_name",
                m_conn
            );

            // dat_item_priceのデータアダプタ構築
            // selectコマンド
            m_da_dat_item_price.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " item_id"
                +     ", vendor_id"
                +     ", price"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " dat_item_price"
                + " order by item_id, vendor_id",
                m_conn
            );
            // insertコマンド
            m_da_dat_item_price.InsertCommand = new NpgsqlCommand
            (
                   "insert into dat_item_price ("
                +      " item_id"
                +     ", vendor_id"
                +     ", price"
                + " ) values ("
                +      " :item_id"
                +     ", :vendor_id"
                +     ", :price"
                + " )",
                m_conn
            );
            m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("item_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            m_da_dat_item_price.InsertCommand.Parameters.Add(new NpgsqlParameter("price"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_dat_item_price.UpdateCommand = new NpgsqlCommand
            (
                   "update dat_item_price set"
                +      " vendor_id=:vendor_id"
                +     ", price=:price"
                +     ", update_date=current_timestamp"
                + " where"
                +      " item_id=:item_id"
                +  " and vendor_id=:org_vendor_id",
                m_conn
            );
            m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_id"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("price"        , NpgsqlTypes.NpgsqlDbType.Integer, 0, "price"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id"      , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            m_da_dat_item_price.UpdateCommand.Parameters.Add(new NpgsqlParameter("org_vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_dat_item_price.DeleteCommand = new NpgsqlCommand
            (
                   "delete from dat_item_price"
                + " where"
                +      " item_id=:item_id"
                +  " and vendor_id=:vendor_id",
                m_conn
            );
            m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            m_da_dat_item_price.DeleteCommand.Parameters.Add(new NpgsqlParameter("vendor_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdatedイベントの追加
            m_da_dat_item_price.RowUpdated += new NpgsqlRowUpdatedEventHandler(dat_item_priceRowUpdated);

            // mst_vendorのデータアダプタ(グリッドのコンボボックス用)
            // selectコマンド
            m_da_mst_vendor.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " vendor_id"
                +     ", vendor_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_vendor"
                + " order by vendor_id",
                m_conn
            );

            // データセット生成
            m_da_mst_item.Fill(m_ds, "mst_item");
            m_da_mst_category.Fill(m_ds, "mst_category");
            m_da_dat_item_price.Fill(m_ds, "dat_item_price");
            m_da_mst_vendor.Fill(m_ds, "mst_vendor");

            // mst_itemのitem_idをAutoIncrementにする
            DataColumn dc_item_id = m_ds.Tables["mst_item"].Columns["item_id"];
            dc_item_id.AutoIncrement = true;
            dc_item_id.AutoIncrementSeed = -1;
            dc_item_id.AutoIncrementStep = -1;

            // リレーション作成
            m_ds.Relations.Add(new DataRelation("rel_dat_item_price",
                                                m_ds.Tables["mst_item"].Columns["item_id"],
                                                m_ds.Tables["dat_item_price"].Columns["item_id"]));

            // bind_mst_itemを設定
            bind_mst_item.DataSource = m_ds;
            bind_mst_item.DataMember = "mst_item";

            // bind_dat_item_priceを設定
            bind_dat_item_price.DataSource = bind_mst_item;
            bind_dat_item_price.DataMember = "rel_dat_item_price";

            // カラムの関連付け
            /// mst_item
            col_item_id.DataPropertyName     = "item_id";
            col_item_name.DataPropertyName   = "item_name";
            col_category_id.DataPropertyName = "category_id";
            col_category_id.DataSource       = m_ds.Tables["mst_category"];
            col_category_id.DisplayMember    = "category_name";
            col_category_id.ValueMember      = "category_id";
            col_create_date.DataPropertyName = "create_date";
            col_update_date.DataPropertyName = "update_date";
            // dat_item_price
            col_dat_item_id.DataPropertyName     = "item_id";
            col_dat_vendor_id.DataPropertyName   = "vendor_id";
            col_dat_vendor_id.DataSource         = m_ds.Tables["mst_vendor"];
            col_dat_vendor_id.DisplayMember      = "vendor_name";
            col_dat_vendor_id.ValueMember        = "vendor_id";
            col_dat_price.DataPropertyName       = "price";
            col_dat_create_date.DataPropertyName = "create_date";
            col_dat_update_date.DataPropertyName = "update_date";
        }

        // 保存ボタンのクリック
        private void cmd_save_Click(object sender, EventArgs e)
        {
            int update_count = 0;
            try
            {
                // delete
                update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted));
                update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted));
                // update
                update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent));
                update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent));
                // insert
                update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added));
                update_count += m_da_dat_item_price.Update(m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added));
            }
            catch (Exception ex)
            {
                MessageBox.Show("商品の保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        // mst_itemのデータアダプタのRowUpdatedイベント
        private void mst_itemRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // item_idとcreate_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select item_id, create_date, update_date from mst_item where item_id=currval('mst_item_item_id_seq')", m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["item_id"] = reader["item_id"];
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if (e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_item where item_id="+e.Row["item_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        // dat_item_priceのデータアダプタのRowUpdatedイベント
        private void dat_item_priceRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // create_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select create_date, update_date from dat_item_price where item_id="+e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if (e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from dat_item_price where item_id=" + e.Row["item_id"].ToString()+" and vendor_id="+e.Row["vendor_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        private void form_mst_item_FormClosing(object sender, FormClosingEventArgs e)
        {
            int update_count = 0;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added).Length;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted).Length;
            update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Added).Length;
            update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
            update_count += m_ds.Tables["dat_item_price"].Select(null, null, DataViewRowState.Deleted).Length;
            if (update_count > 0)    // 1件以上更新されていれば確認画面を表示
            {
                if (MessageBox.Show("商品が保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }

        }
    }
}

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[リレーション#1]

2007/08/02 21:28

ちょっと間が開きましたが、続きです。

商品編集画面に、ベンダー毎の単価を編集できるように追加します。

まずは、商品編集画面を改造。
現状のform_mst_itemは次のようになっています。
form_mst_item.gif
これに、ベンダー毎の単価を編集するグリッドを追加するので、SplitContainerを使うことにします。
ひとまずコンテナの中にあるSplitContainerを貼り付けて、上下分割にします。
form_mst_item_2.gif
次に、grid_mst_itemとnavi_mst_itemをSplitContainerの上のパネルに移動します。
ドキュメントアウトラインウィンドウを開いて、grid_mst_itemとnavi_mst_itemをsplitContainer1.Panel1の下にドラッグ&ドロップで移動します。
document_outline.gif
SplitContainerがフォーム全体の大きさになるように、Dockをfillに変更します。
dock_fill.gif
あとは、パネル内のgrid_mst_itemとnavi_mst_itemの位置を調整しなおします。

続けて、下のパネルに、ベンダー毎の単価を編集するためのグリッドなどを配置します。
bind_dat_item_priceというBindingSourceを追加し、DataGridViewはgrid_dat_item_price,BindingNavigatorはnavi_dat_item_priceという名前で作成し、それぞれのDataSourceとBindingSourceはbind_dat_item_priceとします。
できたフォームはこんな感じです。
form_mst_item_3.gif
SplitContainerは、パネルを分ける位置をドラッグして移動することができて便利。
でもその掴む位置がわかりにくいです(^^;
枠をつけるとわかりやすくなりますけど、枠の線がうるさい感じでいまひとつ。

grid_dat_item_priceの各列は次のように設定します。
・ID
dat_item_price_item_id.gif
・ベンダー
dat_item_price_vendor_id.gif
・単価
dat_item_price_price.gif
・作成日時
dat_item_price_create_date.gif
・更新日時
dat_item_price_update_date.gif

ベンダー列は、mst_vendorの内容をコンボボックスで選択できるようにします。


ひとまず、今回は画面まで。
次回はmst_itemとdat_item_priceのリレーションを作成して、grid_mst_itemとgrid_dat_item_priceが連動するようにしていきます。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[一休み]

2007/07/18 21:54

前回の続きですが、今回は前にやったことの繰り返し。

ベンダーを登録する画面を作ります。
内容はカテゴリの登録と同じです(^^;

フォームは以下のとおり。
form_mst_vendor.gif

ソースは次のとおりです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;

namespace Npgsql_sample
{
    public partial class form_mst_vendor : Form
    {
        // メンバ変数
        // データベース接続子
        private NpgsqlConnection m_conn = new NpgsqlConnection
        (
              "Server=localhost;"
            + "Port=5432;"
            + "User Id=Npgsql_sample;"
            + "Password=hogehoge;"
            + "Database=Npgsql_sample;"
            + "Encoding=UNICODE"
        );
        // mst_vendorのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_vendor = new NpgsqlDataAdapter();
        // データセット
        private DataSet m_ds = new DataSet();

        public form_mst_vendor()
        {
            InitializeComponent();
        }

        private void form_mst_vendor_Load(object sender, EventArgs e)
        {
            // mst_vendorのデータアダプタ構成
            // selectコマンド
            m_da_mst_vendor.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " vendor_id"
                +     ", vendor_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_vendor"
                + " order by vendor_name",
                m_conn
            );
            // insertコマンド
            m_da_mst_vendor.InsertCommand = new NpgsqlCommand
            (
                   "insert into mst_vendor ("
                +      " vendor_name"
                + " ) values ("
                +      " :vendor_name"
                + " )",
                m_conn
            );
            m_da_mst_vendor.InsertCommand.Parameters.Add(new NpgsqlParameter("vendor_name", NpgsqlTypes.NpgsqlDbType.Text, 0, "vendor_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_mst_vendor.UpdateCommand = new NpgsqlCommand
            (
                "update mst_vendor set"
                + " vendor_name=:vendor_name"
                + ", update_date=current_timestamp"
                + " where"
                + " vendor_id=:vendor_id",
                m_conn
            );
            m_da_mst_vendor.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_name", NpgsqlTypes.NpgsqlDbType.Text   , 0, "vendor_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_vendor.UpdateCommand.Parameters.Add(new NpgsqlParameter("vendor_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_mst_vendor.DeleteCommand = new NpgsqlCommand
            (
                   "delete from mst_vendor"
                + " where"
                +      " vendor_id=:vendor_id",
                m_conn
            );
            m_da_mst_vendor.DeleteCommand.Parameters.Add(new NpgsqlParameter("vendor_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "vendor_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdateイベントの追加
            m_da_mst_vendor.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_vendorRowUpdated);

            // データセット生成
            m_da_mst_vendor.Fill(m_ds, "mst_vendor");

            // bind_mst_vendorを設定
            bind_mst_vendor.DataSource = m_ds;
            bind_mst_vendor.DataMember = "mst_vendor";

            // カラムを関連付け
            col_vendor_id.DataPropertyName   = "vendor_id";
            col_vendor_name.DataPropertyName = "vendor_name";
            col_create_date.DataPropertyName = "create_date";
            col_update_date.DataPropertyName = "update_date";
        }

        // 保存ボタンをクリック
        private void cmd_save_Click(object sender, EventArgs e)
        {
            int update_count = 0;
            try
            {
                update_count += m_da_mst_vendor.Update(m_ds.Tables["mst_vendor"]);
            }
            catch (Exception ex)
            {
                MessageBox.Show("ベンダーの保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        // mst_vendorのデータアダプタのRowUpdatedイベント
        private void mst_vendorRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // vendor_idとcreate_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select vendor_id, create_date, update_date from mst_vendor where vendor_id=currval('mst_vendor_vendor_id_seq')", m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["vendor_id"]   = reader["vendor_id"];
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if (e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_vendor where vendor_id=" + e.Row["vendor_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        // フォームを閉じるときのイベント
        private void form_mst_vendor_FormClosing(object sender, FormClosingEventArgs e)
        {
            int update_count = 0;
            update_count += m_ds.Tables["mst_vendor"].Select(null, null, DataViewRowState.Added).Length;
            update_count += m_ds.Tables["mst_vendor"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
            update_count += m_ds.Tables["mst_vendor"].Select(null, null, DataViewRowState.Deleted).Length;
            if (update_count > 0)    // 1件以上更新されていれば確認画面を表示
            {
                if (MessageBox.Show("ベンダーが保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }

        }
    }
}

次は、商品編集画面にベンダーごとの単価を登録できるようにします。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[DataGridViewでコンボボックス]

2007/07/17 23:02

また前回の続きです。
今回はmst_itemの編集画面を作ります。

このmst_itemは商品を登録しますが、その商品がどのカテゴリのものかをコンボボックスで選択できるようにします。
フォームform_mst_itemは次のように作成します。
form_mst_item.gif
bind_mst_itemというBindingSourceを作成し、DataGridViewはmst_item,BindingNavigationをnavi_mst_itemという名前で作成し、それぞれのDataSourceとBindingSourceはbind_mst_itemを設定します。
このあたりは前回と同様です。

grid_mst_itemには、非バインド列として

  • ID
  • 商品名
  • カテゴリ
  • 作成日時
  • 更新日時
を追加します。 このとき、カテゴリ列はコンボボックスで選択できるようにしたいので、ColumnTypeをDataGridViewComboBoxColumnにします。
mst_item_category_id.gif

次にコードを編集していきます。
基本的には前回までのform_mst_categoryと同様です。

クラスのメンバ変数に、テーブルmst_itemとmst_categoryのデータアダプタとデータセットを用意します。
// mst_itemのデータアダプタ
private NpgsqlDataAdapter m_da_mst_item = new NpgsqlDataAdapter();
// mst_categoryのデータアダプタ
private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
// データセット
private DataSet m_ds = new DataSet();
このmst_categoryのデータアダプタはカテゴリを選択するコンボボックスのためのもので、コマンドもSelectCommandのみ用意します。
// mst_categoryのデータアダプタ構築(グリッドのコンボボックス用)
m_da_mst_category.SelectCommand = new NpgsqlCommand
            (
       "select"
    +      " category_id"
    +     ", category_name"
    +     ", create_date"
    +     ", update_date"
    + " from"
    +      " mst_category"
    + " order by category_name",
    m_conn
);
mst_itemのデータアダプタは前回のform_mst_categoryのmst_categoryデータアダプタと同様にInsertCommand,UpdateCommand,DeleteCommandを用意しておきます。

生成したデータアダプタをデータセットにセットします。
// データセット生成
m_da_mst_item.Fill(m_ds, "mst_item");
m_da_mst_category.Fill(m_ds, "mst_category");

カラムを関連付けるとき、カテゴリ列はColumnTypeをDataGridViewComboBoxColumnにしているため、そのデータソースを設定します。
col_category_id.DataPropertyName = "category_id";
col_category_id.DataSource       = m_ds.Tables["mst_category"];
col_category_id.DisplayMember    = "category_name";
col_category_id.ValueMember      = "category_id";
col_category_id.DataSourceにmst_categoryのデータテーブルを設定します。
データテーブルの列のうち、category_nameを画面に表示し、実際設定される値をcategory_idとしています。

実行すると、次のような画面になります。
mst_item_1.gif
カテゴリ列はコンボボックスで選択するようになります。
mst_item_2.gif
WindowsXPだとコンボボックスはそれほど目立たないですが、Vistaで見るとやたら目立ちますね。
その場合は、カテゴリ列のDisplayStyleForCurrentCellOnlyをtrueにすると、カレントセルになったときだけコンボボックスが表示されるようになるので、うるさくないかもです。

ソース全体はこんな感じです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;

namespace Npgsql_sample
{
    public partial class form_mst_item : Form
    {
        // メンバ変数
        // データベース接続子
        private NpgsqlConnection m_conn = new NpgsqlConnection
        (
              "Server=localhost;"
            + "Port=5432;"
            + "User Id=Npgsql_sample;"
            + "Password=hogehoge;"
            + "Database=Npgsql_sample;"
            + "Encoding=UNICODE"
        );
        // mst_itemのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_item = new NpgsqlDataAdapter();
        // mst_categoryのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
        // データセット
        private DataSet m_ds = new DataSet();

        public form_mst_item()
        {
            InitializeComponent();
        }

        private void form_mst_item_Load(object sender, EventArgs e)
        {
            // mst_itemのテーブルアダプタ構築
            // selectコマンド
            m_da_mst_item.SelectCommand = new NpgsqlCommand
            (
                    "select"
                +      " item_id"
                +     ", item_name"
                +     ", category_id"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_item"
                + " order by item_name",
                m_conn
            );
            // insertコマンド
            m_da_mst_item.InsertCommand = new NpgsqlCommand
            (
                   "insert into mst_item ("
                +      " item_name"
                +     ", category_id"
                + " ) values ("
                +      " :item_name"
                +     ", :category_id"
                + " )",
                m_conn
            );
            m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("item_name"  , NpgsqlTypes.NpgsqlDbType.Text   , 0, "item_name"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            m_da_mst_item.InsertCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_mst_item.UpdateCommand = new NpgsqlCommand
            (
                   "update mst_item set"
                +      " item_name=:item_name"
                +     ", category_id=:category_id"
                +     ", update_date=current_timestamp"
                + " where"
                +      " item_id=:item_id",
                m_conn
            );
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_name"  , NpgsqlTypes.NpgsqlDbType.Text   , 0, "item_name"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_item.UpdateCommand.Parameters.Add(new NpgsqlParameter("item_id"    , NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id"    , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_mst_item.DeleteCommand = new NpgsqlCommand
            (
                   "delete from mst_item"
                + " where"
                +      " item_id=:item_id",
                m_conn
            );
            m_da_mst_item.DeleteCommand.Parameters.Add(new NpgsqlParameter("item_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "item_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdatedイベントの追加
            m_da_mst_item.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_itemRowUpdated);

            // mst_categoryのデータアダプタ構築(グリッドのコンボボックス用)
            m_da_mst_category.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " category_id"
                +     ", category_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_category"
                + " order by category_name",
                m_conn
            );

            // データセット生成
            m_da_mst_item.Fill(m_ds, "mst_item");
            m_da_mst_category.Fill(m_ds, "mst_category");

            // bind_mst_itemを設定
            bind_mst_item.DataSource = m_ds;
            bind_mst_item.DataMember = "mst_item";

            // カラムの関連付け
            col_item_id.DataPropertyName     = "item_id";
            col_item_name.DataPropertyName   = "item_name";
            col_category_id.DataPropertyName = "category_id";
            col_category_id.DataSource       = m_ds.Tables["mst_category"];
            col_category_id.DisplayMember    = "category_name";
            col_category_id.ValueMember      = "category_id";
            col_create_date.DataPropertyName = "create_date";
            col_update_date.DataPropertyName = "update_date";
        }

        // 保存ボタンのクリック
        private void cmd_save_Click(object sender, EventArgs e)
        {
            int update_count = 0;
            try
            {
                update_count += m_da_mst_item.Update(m_ds.Tables["mst_item"]);
            }
            catch (Exception ex)
            {
                MessageBox.Show("商品の保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        // mst_itemのデータアダプタのRowUpdatedイベント
        private void mst_itemRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // item_idとcreate_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select item_id, create_date, update_date from mst_item where item_id=currval('mst_item_item_id_seq')", m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["item_id"] = reader["item_id"];
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if (e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_item where item_id="+e.Row["item_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        private void form_mst_item_FormClosing(object sender, FormClosingEventArgs e)
        {
            int update_count = 0;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Added).Length;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
            update_count += m_ds.Tables["mst_item"].Select(null, null, DataViewRowState.Deleted).Length;
            if (update_count > 0)    // 1件以上更新されていれば確認画面を表示
            {
                if (MessageBox.Show("商品が保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }

        }
    }
}

次回はベンダの編集画面を作ります。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[BindingNavigator]

2007/07/16 22:52

また前回の続きです。
前回ひとまずmst_categoryの編集画面を作りましたが、これにBindNavigatorを追加してみます。

フォームform_mst_categoryを次のように変更します。
form_mst_category2.gif
navi_mst_categoryという名前でBindingNavigatorを追加して、DockをBottomにしています。
grid_mst_categoryもフォームの枠いっぱいに広げてみました。
bind_mst_categoryというBindingSourceを追加して、navi_mst_categoryのbindingSourceに、またgrid_mst_categoryのDataSourceに設定します。

フォームいっぱいに使っているので、保存ボタンを削除してnavi_mst_categoryに保存ボタンを追加します。
save.png
また、名前もcmd_saveとし、Clickイベントの関数には削除した保存ボタンのイベント関数cmd_save_Clickをそのまま割り当てます。

次にフォームロードイベント内で、前回データセットを生成したところの下で、bind_mst_categoryのDataSrouceとDataMemberをセットします。

// bind_mst_categoryを設定
bind_mst_category.DataSource = m_ds;
bind_mst_category.DataMember = "mst_category";

今回、grid_mst_categoryのDataSourceはすでにbind_mst_categoryが設定してあるので、前回のソース
// グリッドと接続
grid_mst_category.AutoGenerateColumns = false;
grid_mst_category.DataSource = m_ds;
grid_mst_category.DataMember = "mst_category";
は削除します。

あと、データを編集して保存せずにフォームを閉じるとき、警告を出すようにします。
form_mst_categoryのFormClosingイベントを以下のようにします。
// フォームを閉じるときのイベント
private void form_mst_category_FormClosing(object sender, FormClosingEventArgs e)
{
    int update_count = 0;
    update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.Added).Length;
    update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
    update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.Deleted).Length;
    if (update_count > 0)    // 1件以上更新されていれば確認画面を表示
    {
        if (MessageBox.Show("カテゴリが保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
        {
            e.Cancel = true;
        }
    }
}
mst_category_6.gif

動かすとこんな感じになります。
mst_category_7.gif

ソース全体はこんな感じです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;

namespace Npgsql_sample
{
    public partial class form_mst_category : Form
    {
        // メンバ変数
        // データベース接続子
        private NpgsqlConnection m_conn = new NpgsqlConnection
        (
              "Server=localhost;"
            + "Port=5432;"
            + "User Id=Npgsql_sample;"
            + "Password=hogehoge;"
            + "Database=Npgsql_sample;"
            + "Encoding=UNICODE"
        );
        // mst_categoryのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
        // データセット
        private DataSet m_ds = new DataSet();

        // コンストラクタ
        public form_mst_category()
        {
            InitializeComponent();
        }

        // フォームロードイベント
        private void form_mst_category_Load(object sender, EventArgs e)
        {
            // mst_categoryのデータアダプタ構築
            // selectコマンド
            m_da_mst_category.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " category_id"
                +     ", category_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_category"
                + " order by category_name",
                m_conn
            );
            // insertコマンド
            m_da_mst_category.InsertCommand = new NpgsqlCommand
            (
                   "insert into mst_category ("
                +      " category_name"
                + " ) values ("
                +      " :category_name"
                + " )",
                m_conn
            );
            m_da_mst_category.InsertCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text, 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_mst_category.UpdateCommand = new NpgsqlCommand
            (
                   "update mst_category set"
                +      " category_name=:category_name"
                +     ", update_date=current_timestamp"
                + " where"
                +      " category_id=:category_id",
                m_conn
            );
            m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text   , 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_mst_category.DeleteCommand = new NpgsqlCommand
            (
                   "delete from mst_category"
                + " where"
                +      " category_id=:category_id",
                m_conn
            );
            m_da_mst_category.DeleteCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdateイベントの追加
            m_da_mst_category.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_categoryRowUpdated);

            // データセット生成
            m_da_mst_category.Fill(m_ds, "mst_category");

            // bind_mst_categoryを設定
            bind_mst_category.DataSource = m_ds;
            bind_mst_category.DataMember = "mst_category";

            // カラムを関連付け
            col_category_id.DataPropertyName   = "category_id";
            col_category_name.DataPropertyName = "category_name";
            col_create_date.DataPropertyName   = "create_date";
            col_update_date.DataPropertyName   = "update_date";
        }

        // 保存ボタンのクリック
        private void cmd_save_Click(object sender, EventArgs e)
        {
            int update_count = 0;
            try
            {
                update_count += m_da_mst_category.Update(m_ds.Tables["mst_category"]);
            }
            catch (Exception ex)
            {
                MessageBox.Show("カテゴリの保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        // mst_categoryのデータアダプタのRowUpdatedイベント
        private void mst_categoryRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // category_idとcreate_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select category_id, create_date, update_date from mst_category where category_id=currval('mst_category_category_id_seq')", m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["category_id"] = reader["category_id"];
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if ( e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_category where category_id="+e.Row["category_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        // フォームを閉じるときのイベント
        private void form_mst_category_FormClosing(object sender, FormClosingEventArgs e)
        {
            int update_count = 0;
            update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.Added).Length;
            update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.ModifiedCurrent).Length;
            update_count += m_ds.Tables["mst_category"].Select(null, null, DataViewRowState.Deleted).Length;
            if (update_count > 0)    // 1件以上更新されていれば確認画面を表示
            {
                if (MessageBox.Show("カテゴリが保存されていません。\n本当に閉じますか?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }
        }
    }
}

次はmst_itemテーブルを編集するフォームを追加します。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[データ編集]

2007/07/14 14:48

前回の続きです。
カテゴリ情報を保存する、mst_categoryを編集するフォームを作ります。
作り方としてこういうやり方がいいのかまだ試行錯誤してるので、もっとちゃんとしたやり方もあるのかもしれません。間違った情報だったらゴメンナサイ(^^;


クラス名はform_mst_categoryとし、外観はこんな感じ。
form_mst_category.gif
DataGridViewをgrid_mst_categoryという名前で作成。
保存ボタンをcmd_saveという名前で作成。
grid_mst_categoryには、非バインド列として

  • ID
  • カテゴリ名
  • 作成日時
  • 更新日時
を追加します。
各列は次のとおり。
・ID
mst_category_category_id.gif
・カテゴリ名
mst_category_category_name.gif
・作成日時
mst_category_create_date.gif
・更新日時
mst_category_update_date.gif

Npgsqlを使うため、usingを追加します。
using Npgsql;

クラスのメンバ変数として、データベース接続子を追加。
// データベース接続子
private NpgsqlConnection m_conn = new NpgsqlConnection
(
      "Server=localhost;"
    + "Port=5432;"
    + "User Id=Npgsql_sample;"
    + "Password=hogehoge;"
    + "Database=Npgsql_sample;"
    + "Encoding=UNICODE"
);
テーブルmst_categoryのデータアダプタとデータセットも用意します。
// mst_categoryのデータアダプタ
private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
// データセット
private DataSet m_ds = new DataSet();
※C#でメンバ変数の頭にm_をつけるのって一般的なのかよくわかりませんけど、VC++&MFCでプログラム作ってたころの名残でなんとなくそうしてます。本来はDelphiの命名ルールが近いのかな?まぁ個人的にはわかればいいじゃん程度に考えています(^^;
データベース接続子は、ホントはユーザーが設定できるようにしないといけないでしょうけど、ひとまずフォーム毎に直接書いてます。

次にフォームロードイベントを追加して、ここでmst_categoryテーブルのデータアダプタとデータセットを準備します。
まず、mst_categoryテーブルのデータアダプタを構築します。
selectコマンドを追加します。
// selectコマンド
m_da_mst_category.SelectCommand = new NpgsqlCommand
(
       "select"
    +      " category_id"
    +     ", category_name"
    +     ", create_date"
    +     ", update_date"
    + " from"
    +      " mst_category"
    + " order by category_name",
    m_conn
);
次にinsertコマンド。
// insertコマンド
m_da_mst_category.InsertCommand = new NpgsqlCommand
(
       "insert into mst_category ("
    +      " category_name"
    + " ) values ("
    +      " :category_name"
    + " )",
    m_conn
);
m_da_mst_category.InsertCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text, 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
SQLで、category_name列に入れる情報は、頭に:をつけて:categoryと記述します。
そして、その:categoryはParametersにNpgsqlParameterを追加します。
第二引数のparameterTypeはDbTypeのメンバを指定するのかなっとも思いましたが、NpgsqlTypes.NpgsqlDbTypeにPostgreSQLのデータタイプがあったので、こちらを指定しています。
次にupdateコマンド。
// updateコマンド
m_da_mst_category.UpdateCommand = new NpgsqlCommand
(
       "update mst_category set"
    +      " category_name=:category_name"
    +     ", update_date=current_timestamp"
    + " where"
    +      " category_id=:category_id",
    m_conn
);
m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text   , 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
ここで、パラメータとして、
  • category_nameは入力は変更された値
  • whereの条件となるcategory_idは元の値(category_idは表示のみなので変更はできませんが)
となるため、第9引数のsourceVersionはおのおの
  • category_nameはDataRowVersion.Current(現在の値)
  • category_idはDataRowVersion.Original(元の値)
とします。
あとdeleteコマンド。
// deleteコマンド
m_da_mst_category.DeleteCommand = new NpgsqlCommand
(
       "delete from mst_category"
    + " where"
    +      " category_id=:category_id",
    m_conn
);
m_da_mst_category.DeleteCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));

次にデータセットを準備します。
// データセット生成
m_da_mst_category.Fill(m_ds, "mst_category");

準備したデータセットとグリッドを繋ぎます。
// グリッドと接続
grid_mst_category.AutoGenerateColumns = false;
grid_mst_category.DataSource = m_ds;
grid_mst_category.DataMember = "mst_category";
今回はデータセットを自分でメンバ変数として追加しているため、フォーム編集画面ではgrid_mst_categoryのプロパティDataSourceとDataMemberには何も入れていないため、ここで設定しています。
また、AutoGenerateColumnsをfalseにしておかないと、自動的にmst_categoryのselectコマンドの列が追加されてしまいます。

グリッドに非バインド列として追加していた各列のプロパティDataPorpertyNameにデータアダプタの列名を設定して、DataMemberと繋ぎます。
// カラムを関連付け
col_category_id.DataPropertyName   = "category_id";
col_category_name.DataPropertyName = "category_name";
col_create_date.DataPropertyName   = "create_date";
col_update_date.DataPropertyName   = "update_date";
ここまでがフォームロードイベント関数。

今度は保存ボタンをクリックされたときのイベント関数。
ここではデータの更新を行います。
int update_count = 0;
try
{
    update_count += m_da_mst_category.Update(m_ds.Tables["mst_category"]);
}
catch (Exception ex)
{
    MessageBox.Show("カテゴリの保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}
MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
mst_categoryテーブルのデータアダプタのUpdateメソッドで更新します。
Updateメソッドでは更新した件数が返ってくるようなので、正常終了したときはその件数を表示しています。

ここまでで、form_mst_categoryはひとまず完成。
メインフォームにボタンを追加してform_mst_categoryが開くようにします。
private void button1_Click(object sender, EventArgs e)
{
    form_mst_category f_mst_category = new form_mst_category();
    f_mst_category.ShowDialog();
}
これで完成。


実際に動かして、form_mst_categoryを開くと次のような画面が表示されます。
mst_category_1.gif
次のようにデータを入力してみます。
mst_category_2.gif
保存ボタンをクリックすると、入力されたデータが保存されます。
mst_category_3.gif
ただし、今の状況では、ID列や作成日時,更新日時列が表示されません。
が、テーブルmst_categoryにはちゃんと保存されています。
Npgsql_sample=> select * from mst_category;
 category_id | category_name |       create_date       |       update_date
-------------+---------------+-------------------------+-------------------------
           1 | テレビ        | 2007-07-14 14:09:10.848 | 2007-07-14 14:09:10.848
           2 | HDDレコーダ   | 2007-07-14 14:09:10.852 | 2007-07-14 14:09:10.852
(2 rows)

保存したとき、serialで取得されたcategory_idや日付などを入れるようにしてみます。
取得するタイミングとしては、テーブルmst_categoryのデータアダプタのRowUpdatedイベントで行います。
RowUpdatedイベントの関数を次のように作成します。
// mst_categoryのデータアダプタのRowUpdatedイベント
private void mst_categoryRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
{
    if (e.Status == UpdateStatus.Continue)
    {
        if (e.StatementType == StatementType.Insert)
        {
            // category_idとcreate_date,update_dateを取得
            NpgsqlCommand cmd = new NpgsqlCommand("select category_id, create_date, update_date from mst_category where category_id=currval('mst_category_category_id_seq')", m_conn);
            try
            {
                NpgsqlDataReader reader = cmd.ExecuteReader();
                reader.Read();
                e.Row["category_id"] = reader["category_id"];
                e.Row["create_date"] = reader["create_date"];
                e.Row["update_date"] = reader["update_date"];
            }
            catch (Exception)
            {
                throw;
            }
        }
        else if ( e.StatementType == StatementType.Update)
        {
            // update_dateを取得
            NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_category where category_id="+e.Row["category_id"].ToString(), m_conn);
            try
            {
                NpgsqlDataReader reader = cmd.ExecuteReader();
                reader.Read();
                e.Row["update_date"] = reader["update_date"];
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
作成したイベント関数を追加します。
// RowUpdateイベントの追加
m_da_mst_category.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_categoryRowUpdated);

これでもう一行追加してみます。
mst_category_4.gif
今度は保存された後、IDや作成日時,更新日時が表示されます。
mst_category_5.gif

これで一応完成。

ソース全体はこんな感じです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Npgsql;

namespace Npgsql_sample
{
    public partial class form_mst_category : Form
    {
        // メンバ変数
        // データベース接続子
        private NpgsqlConnection m_conn = new NpgsqlConnection
        (
              "Server=localhost;"
            + "Port=5432;"
            + "User Id=Npgsql_sample;"
            + "Password=hogehoge;"
            + "Database=Npgsql_sample;"
            + "Encoding=UNICODE"
        );
        // mst_categoryのデータアダプタ
        private NpgsqlDataAdapter m_da_mst_category = new NpgsqlDataAdapter();
        // データセット
        private DataSet m_ds = new DataSet();

        // コンストラクタ
        public form_mst_category()
        {
            InitializeComponent();
        }

        // フォームロードイベント
        private void form_mst_category_Load(object sender, EventArgs e)
        {
            // mst_categoryのデータアダプタ構築
            // selectコマンド
            m_da_mst_category.SelectCommand = new NpgsqlCommand
            (
                   "select"
                +      " category_id"
                +     ", category_name"
                +     ", create_date"
                +     ", update_date"
                + " from"
                +      " mst_category"
                + " order by category_name",
                m_conn
            );
            // insertコマンド
            m_da_mst_category.InsertCommand = new NpgsqlCommand
            (
                   "insert into mst_category ("
                +      " category_name"
                + " ) values ("
                +      " :category_name"
                + " )",
                m_conn
            );
            m_da_mst_category.InsertCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text, 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current, DBNull.Value));
            // updateコマンド
            m_da_mst_category.UpdateCommand = new NpgsqlCommand
            (
                   "update mst_category set"
                +      " category_name=:category_name"
                +     ", update_date=current_timestamp"
                + " where"
                +      " category_id=:category_id",
                m_conn
            );
            m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_name", NpgsqlTypes.NpgsqlDbType.Text   , 0, "category_name", ParameterDirection.Input, false, 0, 0, DataRowVersion.Current , DBNull.Value));
            m_da_mst_category.UpdateCommand.Parameters.Add(new NpgsqlParameter("category_id"  , NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id"  , ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // deleteコマンド
            m_da_mst_category.DeleteCommand = new NpgsqlCommand
            (
                   "delete from mst_category"
                + " where"
                +      " category_id=:category_id",
                m_conn
            );
            m_da_mst_category.DeleteCommand.Parameters.Add(new NpgsqlParameter("category_id", NpgsqlTypes.NpgsqlDbType.Integer, 0, "category_id", ParameterDirection.Input, false, 0, 0, DataRowVersion.Original, DBNull.Value));
            // RowUpdateイベントの追加
            m_da_mst_category.RowUpdated += new NpgsqlRowUpdatedEventHandler(mst_categoryRowUpdated);

            // データセット生成
            m_da_mst_category.Fill(m_ds, "mst_category");

            // グリッドと接続
            grid_mst_category.AutoGenerateColumns = false;
            grid_mst_category.DataSource = m_ds;
            grid_mst_category.DataMember = "mst_category";
            // カラムを関連付け
            col_category_id.DataPropertyName   = "category_id";
            col_category_name.DataPropertyName = "category_name";
            col_create_date.DataPropertyName   = "create_date";
            col_update_date.DataPropertyName   = "update_date";
        }

        // 保存ボタンのクリック
        private void cmd_save_Click(object sender, EventArgs e)
        {
            int update_count = 0;
            try
            {
                update_count += m_da_mst_category.Update(m_ds.Tables["mst_category"]);
            }
            catch (Exception ex)
            {
                MessageBox.Show("カテゴリの保存に失敗しました。\n\n[内容]\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            MessageBox.Show(update_count.ToString() + "件、保存しました。", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        // mst_categoryのデータアダプタのRowUpdatedイベント
        private void mst_categoryRowUpdated(Object sender, NpgsqlRowUpdatedEventArgs e)
        {
            if (e.Status == UpdateStatus.Continue)
            {
                if (e.StatementType == StatementType.Insert)
                {
                    // category_idとcreate_date,update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select category_id, create_date, update_date from mst_category where category_id=currval('mst_category_category_id_seq')", m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["category_id"] = reader["category_id"];
                        e.Row["create_date"] = reader["create_date"];
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else if ( e.StatementType == StatementType.Update)
                {
                    // update_dateを取得
                    NpgsqlCommand cmd = new NpgsqlCommand("select update_date from mst_category where category_id="+e.Row["category_id"].ToString(), m_conn);
                    try
                    {
                        NpgsqlDataReader reader = cmd.ExecuteReader();
                        reader.Read();
                        e.Row["update_date"] = reader["update_date"];
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }
    }
}


一応これで編集はできますけど、BindingNavigatorがあると使いやすくなると思うので、次はこれにBindingNavigatorをつけてみようと思います。

投稿者: kkino :  パーマリンク | コメント (0) | トラックバック (0)

NpgsqlでPostgreSQLにアクセス[準備]

2007/07/11 21:58

PostgreSQLの.NETプロバイダのNpgsqlを使ってデータベースにアクセスするプログラムを作ったりしてたので、そのまとめ。

1. まず、WindowsにPostgreSQLをインストール。
PostgreSQLは別のサーバーでもいいですけど、お手軽にクライアントPCにWindows版をインストールしてます。
Windows版PostgreSQL8.2.4
普通にインストールすると、C:\Program Files\PostgreSQL\8.2\NpgsqlにNpgsqlも入るので、これを使っていきます。
Npgsqlだけ入れたいときは、GBlogさんからNpgsqlだけダウンロードできそうです。

2. サンプル用のデータベース作成。
まず、サンプル用データベースのオーナーにNpgsql_sampleを作成。パスワードはhogehogeにしておきます。
次にサンプル用データベースをNpgsql_sampleという名前で作成。エンコーディングはUTF-8を選択します。
sample_database.gif
こんな感じ。

3. サンプルのテーブルを作成。
何かの商品の、卸ベンダ毎の単価を保存するものを例として作っていこうと思います。
簡単なER図(しかも適当な書式)は以下の感じ。
er.png

テーブル作成のSQLは以下のとおり。

-- カテゴリ
create table mst_category
(
	category_id    serial    not null  -- カテゴリID
	                         primary key,
	category_name  text      not null, -- カテゴリ名
	create_date    timestamp not null  -- 作成日時
	                         default current_timestamp,
	update_date    timestamp not null  -- 更新日時
	                         default current_timestamp
);

-- 商品
create table mst_item
(
	item_id        serial    not null  -- 商品ID
	                         primary key,
	item_name      text      not null, -- 商品名
	category_id    integer   not null  -- カテゴリID
	                         references mst_category(category_id),
	create_date    timestamp not null  -- 作成日時
	                         default current_timestamp,
	update_date    timestamp not null  -- 更新日時
	                         default current_timestamp
);

-- ベンダー
create table mst_vendor
(
	vendor_id      serial    not null  -- ベンダーID
	                         primary key,
	vendor_name    text      not null, -- ベンダー名
	create_date    timestamp not null  -- 作成日時
	                         default current_timestamp,
	update_date    timestamp not null  -- 更新日時
	                         default current_timestamp
);

-- ベンダーごとの商品単価
create table dat_item_price
(
	item_id        integer   not null  -- 商品ID
	                         references mst_item(item_id),
	vendor_id      integer   not null  -- ベンダーID
	                         references mst_vendor(vendor_id),
	price          integer   not null, -- 単価
	create_date    timestamp not null  -- 作成日時
	                         default current_timestamp,
	update_date    timestamp not null  -- 更新日時
	                         default current_timestamp,
	primary key ( item_id, vendor_id )
);

4. VisualStudio2005で、新しいプロジェクトを作成。
プロジェクト名をNpgsql_sampleとして、プロジェクトを作成します。
new_project.gif

次にメニューのプロジェクト→参照の追加で、参照タブを選び、インストールされたNpgsql.dll(普通にPostgreSQLをインストールしていればC:\Program Files\PostgreSQL\8.2\Npgsql\Npgsql.dll)を選んでOKボタンを押します。
add_npgsql.gif

これでひとまず準備完了。

投稿者: kkino :  パーマリンク | コメント (3) | トラックバック (0)

玄箱HGをetch化

2007/05/26 20:06

しばらく眠っていた玄箱HGを復活。
etchもリリースされているので、玄箱HGでetchにしてみることに。
玄箱のカーネルをいろいろ用意してくださってる
Genbako kernel collectionさん
に感謝。

まず最初にカーネル2.6版sargeのイメージを
http://www.genbako.com/debian-2.6.17.3/debian-sarge-2.6.17.3-kuroHG-20060702.tgz (ミラー)
からダウンロード。
2.6.20にあげるために
http://www.genbako.com/kernelimage-2.6.20-kuroHG.tgz (ミラー) http://www.genbako.com/modules-2.6.20-kuroHG.tgz (ミラー)
もダウンロード。

前にやった手順で玄箱をdebian化していきます。

1. 玄箱をEMモードにして、HDDを組み込んで電源をON。

2. DHCPでIPアドレスが割り当てられるので、pingなどで適当に探してtelnetで接続。

3. root/kuroadminでログイン。

4. ディスクを割り当て。


# /sbin/mfdisk -e /dev/hda
# sh /sbin/mkfilesystem.sh

5. ダウンロードした
  • debian-sarge-2.6.17.3-kuroHG-20060702.tgz
  • kernelimage-2.6.20-kuroHG.tgz
  • modules-2.6.20-kuroHG.tgz
を/mnt2/shareにftpで転送。

6. 転送したファイルを解凍。

# cd /mnt
# tar zxvf /mnt2/share/debian-sarge-2.6.17.3-kuroHG-20060702.tgz

7. EMモードを抜けて、再起動。

# /usr/bin/write_ok
argv: /usr/bin/write_ok
# reboot

8. 再起動後、IPアドレスが192.168.0.100になっているので、telnetで接続。

9. tmp-kun/tmp-kunでログインして、su - rootでスーパーユーザーに(パスワードはroot)。

10. 適当なユーザーをadduserで作成。rootのパスワードを変更。tmp-kunをdeluserで削除など。

11. カーネルの2.6.20をインストールして再起動。

# cd /boot
# tar zxvf /mnt/share/kernelimage-2.6.20-kuroHG.tgz
# reboot

12. 再起動後、カーネルモジュールを展開。

# apt-get install module-init-tools
# cd /lib/modules
# tar zxvf /mnt/share/modules-2.6.20-kuroHG.tgz
# depmod -a

13. 一応ここまででカーネル2.6.20のsarge環境になるので、パッケージを最新状態に。
/etc/apt/sources.listを

deb http://ftp.jp.debian.org/debian/ sarge main
deb-src http://ftp.jp.debian.org/debian/ sarge main
deb http://security.debian.org/ sarge/updates main
に変更して、

# apt-get update
# apt-get upgrade

14. ここからetch化。
/etc/apt/sources.listを

deb http://ftp.jp.debian.org/debian/ etch main
deb-src http://ftp.jp.debian.org/debian/ etch main
deb http://security.debian.org/ etch/updates main
に変更して、

# apt-get update
# apt-get -u dist-upgrade
途中でいろいろ聞かれるけど、基本デフォルトで。

これで、玄箱HGもetch化できました。

投稿者: kkino :  パーマリンク | コメント (5) | トラックバック (0)

検索


最近のエントリー

カテゴリー

Apache (2)
C# (8)
Delphi (3)
MovableType (1)
Npgsql (7)
Oracle (2)
PHP (2)
PostgreSQL (10)
Windows (3)
XML (1)
ZETA (1)
debian (17)
mysql (1)
ubuntu (1)
その他 (4)
オンラインソフト (1)
玄箱 (13)

アーカイブ

このブログのフィードを取得