2010年3月30日火曜日

[.NET]SqlParameterのパラメータ追加

ADO.NETではプレースホルダを使う場合、たとえばSqlCommand.Parameters.Addします。
しかし、このAddでは、値をセットすることができず、面倒でわかりづらいコードを書く必要がありました。

で、最近発見したんですが、AddWithValueというのが.NET Framework2.0以降で追加されたようです。
コレ使えばそんな問題はなくなりますね。

2010年3月28日日曜日

[他]SQLServerの排他制御

SQLServerはトランザクションをかけると、共有ロックになります。

  • 更新ロック:他のトランザクションからUPDATE, DELETE不可
  • 排他ロック:他のトランザクションからSELECT,UPDATE, DELETE不可


先日、SQLServerで排他制御の実験をしてみました。実施すると、まさしく共有ロックの動作をしていました。

その方法は、SQL文にヒントをつける方法です。以下の組み合わせで実現します。

■ロックの範囲
  • ROWLOCK:行単位のロック
  • PAGLOCK:ページ単位のロック
  • TABLOCK:テーブル単位のロック


■ロックの方式
  • READPAST:ロック行をスキップして取得する(SELECTだけ)
  • UPDLOCK:他のトランザクションからSELECT不可にする
  • XLOCK:排他ロックを強制的に使用(PAGLOCK・TABLOCKのいずれかも指定)


たとえば、ORACLEのFor Update相当にしようとすると、こんな感じ。

SELECT * FROM T_HOGE WITH (ROWLOCK, UPDLOCK)


ほかには、ISOLATION LEVELを変更する方法があるらしいですが、コレは別途整理したいと思います。

2010年3月23日火曜日

[SQL]特定の条件に一致するテーブルの内容を表示する

以前、マスタのみデータを抜きたいということがあり、1000件以下のテーブルのみ、内容の一覧を取得するSQLを書きました。件数の一覧を取るSQLの応用ですが、備忘録代わりにメモ。

--一時変数(結果格納用)
CREATE TABLE #TEMP_TABLE(
     T_NAME varchar(128)
    ,T_CNT int
)

--sp_MSforeachtableでユーザテーブル全部をループ処理
EXEC sp_MSforeachtable  @command1 ='INSERT INTO #TEMP_TABLE;SELECT ''?'' as T_NAME ,COUNT(*) as T_CNT FROM ?'


DECLARE @QUERY nvarchar(128--SQLの一時領域
DECLARE @NAME nvarchar(128--テーブル名一時領域
DECLARE @CNT int --カウント結果

--カーソルの宣言。このSQLの条件を変更することにより、テーブルを絞り込める
DECLARE cs CURSOR FOR
    SELECT T_NAME FROM #TEMP_TABLE WHERE T_CNT > 1 ORDER BY T_NAME

--カーソルのオープン
OPEN cs
FETCH NEXT FROM cs
    INTO @NAME
WHILE @@FETCH_STATUS = 0
BEGIN
    --SELECTを実行する
    PRINT '※※※※' + @NAME 
    SET @QUERY = 'SELECT * FROM ' + @NAME
    EXEC(@QUERY)
    FETCH NEXT FROM cs INTO @NAME
END

CLOSE cs
DEALLOCATE cs

--一時テーブルを削除する
DROP TABLE #TEMP_TABLE

2010年3月19日金曜日

[.NET]知らなかったコレクション(NameValueCollection)

今日は、NameValueCollectionです。このクラスは、1つのキーに対して、複数の値を保持する機能をもつクラスです。たとえば、部→課の関係や課→課員の関係を簡単に作りたいとき便利ですね。でコードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Collections.Specialized;
    NameValueCollection collection = new NameValueCollection();

    collection.Add("第1事業部""1課");
    System.Diagnostics.Debug.WriteLine(collection["第1事業部"], "第1事業部");
    //「第1事業部: 1課」と表示される

    collection.Add("第1事業部""2課");
    System.Diagnostics.Debug.WriteLine(collection["第1事業部"], "第1事業部");
    System.Diagnostics.Debug.WriteLine(collection.GetValues("第1事業部")[0], "第1事業部[0]");
    System.Diagnostics.Debug.WriteLine(collection.GetValues("第1事業部")[1], "第1事業部[1]");
    //「第1事業部: 1課,2課」と表示される
    //「第1事業部[0]: 1課」と表示される
    //「第1事業部[1]: 2課」と表示される
}

2010年3月13日土曜日

[.NET]知らなかったコレクション(ObservableCollection)

今日はObservableCollectionです。このクラス、コレクションに追加削除変更などあると、通知する機能があります。なんとかマネージャ的な用途に使えそう。
よくわかりませんがWPF系のプロジェクトじゃないと使えないらしい。WindowsFormのプロジェクトでは出てきませんでした。というこで、コードは感じ。

private void button1_Click(object sender, RoutedEventArgs e)
{
    //using System.Collections.ObjectModel;
    //using System.Collections.Specialized;
    ObservableCollection<MyItem> collection = new ObservableCollection<MyItem>();
    collection.CollectionChanged += new NotifyCollectionChangedEventHandler(collection_CollectionChanged);

    collection.Add(new MyItem() { key = 1, value1 = "111" });
    collection.Add(new MyItem() { key = 2, value1 = "222" });
    collection.Add(new MyItem() { key = 3, value1 = "333" });
    collection.Add(new MyItem() { key = 4, value1 = "444" });

    collection[2] =new MyItem() { key = 5, value1 = "555" };

    collection.RemoveAt(2);

    //↓のように表示された
    //action=Add NewItems=key=1 
    //action=Add NewItems=key=2 
    //action=Add NewItems=key=3 
    //action=Add NewItems=key=4 
    //action=Replace NewItems=key=5 OldItems=key=3 
    //action=Remove OldItems=key=5 

}

void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("action={0} ",e.Action);

    if (e.NewItems != null && e.NewItems.Count > 0)
    {
        sb.AppendFormat("NewItems={0} ", e.NewItems[0]);
    }
    if (e.OldItems !=null && e.OldItems.Count > 0)
    {
        sb.AppendFormat("OldItems={0} ", e.OldItems[0]);
    }


    System.Diagnostics.Debug.WriteLine(sb.ToString());
}

/// <summary> 
/// コレクションに格納するクラス 
/// </summary> 
public class MyItem
{
    public long key { getset; }
    public string value1 { getset; }
    public string value2 { getset; }
    public string value3 { getset; }

    public override string ToString()
    {
        return string.Format("key={0}", key);

    }
}

2010年3月10日水曜日

[.NET]知らなかったコレクション(ReadOnlyCollection)

知らなかったコレクション第二段。ReadOnlyCollection。ん?どっかで使ったことあるような。。。
このクラスは、ListをReadOnlyにしてくれます。更新しようとするとコンパイルエラーになります。
面白いですね。使い方はこんなかんじ。

//using System.Collections.ObjectModel;

List<string> list = new List<string>();
list.Add("111");
list.Add("222");
list.Add("333");
list.Add("444");

ReadOnlyCollection<string> roList = new ReadOnlyCollection<string>(list);
//↓コンパイルエラー
roList[2] = "hoge";

2010年3月4日木曜日

[.NET]知らなかったコレクション(KeyedCollection)

先日何気に、MSDNを見ていると、使ったことがないコレクション系のクラスをいくつか見つけました。
ということで今回はKeyedCollection。
格納したい情報の中にキーが含まれる場合に、キーを個別に設定するのではなく、格納するオブジェクトの中に含まれるプロパティを使う。というものです。コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    MyKeyedCollection collection = new MyKeyedCollection();
    collection.Add(new MyItem() { key = 1, value1 = "111" });
    collection.Add(new MyItem() { key = 2, value1 = "222" });
    collection.Add(new MyItem() { key = 3, value1 = "333" });
    collection.Add(new MyItem() { key = 4, value1 = "444" });

    System.Diagnostics.Debug.WriteLine(collection[2L].ToString());

    //「key=2, value1=222, value2=, value3=」と表示された。
}

/// <summary>
/// KeyedCollectionの実装 
/// </summary>
public class MyKeyedCollection : KeyedCollection<long, MyItem>
{
    public MyKeyedCollection() { }

    /// <summary>
    /// 指定した要素からキーを抽出する
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    protected override long GetKeyForItem(MyItem item)
    {
        // キーの値を返却する.
        return item.key;
    }

}

/// <summary>
/// コレクションに格納するクラス
/// </summary>
public class MyItem
{
    public long key { getset; }
    public string value1 { getset; }
    public string value2 { getset; }
    public string value3 { getset; }

    public override string ToString()
    {
        return string.Format("key={0}, value1={1}, value2={2}, value3={3}", key, value1, value2, value3);

    }
}

2010年3月3日水曜日

[.NET]WebBrouserコントロールにXMLを表示する

先日WebClientでXMLを取得し、WebBrouserに表示するサンプルを作成していました。
WebBrouserのDocumentTextに取得したテキストを設定するだけで、HTMLはそれらしく表示することができました。で、ためしにXMLを表示してみると、HTMLのように表示されてしまいました。IEでのXML表示のようなることを期待していたのですが。。。

直接、NavigateメソッドでXMLのあるパスをさしてみると、IEのように表示されました。

で、取り合えず、WebClientで取得したXMLをローカルファイルに保存して、NavigateにURIで引き渡すと、IEのように表示されました。とりあえず回避できたもののかっこよくは無いですね。何とかしたいんですが、解決策は見つからず。

2010年3月1日月曜日

[他]スキーマ定義のシンタックス

以前、GDD Blog: [.NET]CSVデータを操作する(OleDb)(その2) で、schema.iniについて少し触れましたが、参考になるページを見つけました!。備忘録代わりにメモ。

方法 : スキーマ定義をテキスト ファイル データ ソースに追加する