2009年8月31日月曜日

[SQL]数値型フィールドで最小の空き番を取得する

先日GDD Blog: [.NET]IDENTITY指定のフィールドはロールバックしても元に戻らない(SQLServerでIDENTITYフィールドの歯抜けについて書きましたが、今日はそれを補完するために、一番小さい空き番を取得するSQLについて書きます。
調べてみると、以下のようなSQLが紹介されていました。

SELECT
    MIN(ID + 1AS GAP
FROM testtable
WHERE (ID+1NOT IN ( SELECT ID FROM testtable);


で、NOT INを使うので、インデックスが使われないのでは?と思い、相関副問い合わせを使ったSQLに書き換えてみました。
SELECT
    MIN(ID + 1AS GAP
FROM testtable
WHERE NOT EXISTS(
    SELECT 'x'
    from testtable t0
    WHERE 
        t0.ID = testtable.ID+1 
)


実行プランを見てみると、結果両方ともインデックスが使われていないことがわかりました。しかし、インデックスなしのフィールドで同SQLを実行すると相関副問い合わせのほうが若干よい結果となりました。
相関副問い合わせであればインデックスが使われるはずなんですが。。。

2009年8月28日金曜日

[.NET]WindowsFormの画面更新系メソッド

WindowsFormで使用できる画面系コントロールの親クラスControlでは、画面再描画の機能がいくつか提供されています。今日は、それらをちょっとまとめてみました。


  • Refresh:強制的に、コントロールがクライアント領域を無効化し、直後にそのコントロール自体とその子コントロールを再描画する

  • Update:コントロールによって、クライアント領域内の無効化された領域が再描画する

  • Invalidate:コントロールの特定の領域を無効にし、そのコントロールに描画メッセージを送信する

との事とらしい。特定のコントロールだけを更新したい場合でかつ即時性が必要ない場合Invalidateで、即時性がある場合Update。親子関係まで含めて更新する場合Refreshといったところでしょうか。

2009年8月25日火曜日

[.NET]一時ファイル名を生成する

ファイル転送や、大量のデータを扱う場合に、一時ファイルに保存したい場合があります。
サーバ的な機能である場合、マルチで動作している場合、重複しないファイル名を生成する必要があります。過去の私の携わったシステムでは、現在日時をミリ秒まで使用し、重複したら連番。みたいな処理を見た記憶があります。で、いまどきは?というと、その手の機能はライブラリに当たり前のように搭載されて。。。いました。使い方も簡単で、コードはこんな感じ。

string file1 = Path.GetTempFileName();
System.Diagnostics.Debug.WriteLine(file1);
//「C:\Users\genz0\AppData\Local\Temp\tmpF27.tmp」と表示されたました。

2009年8月20日木曜日

[.NET]IDENTITY指定のフィールドはロールバックしても元に戻らない(SQLServer

SQLServerにてIDENTITY指定のフィールドがあり、INSERT後にロールバックしてもIDENTITYはカウントアップするという現象が発生しました。
何で戻らないんだ?と思って調べてみると、@@IDENTITY (Transact-SQL)に戻らない的な説明が書いてありました。

GDD Blog: [他]IDENTITYフィールドに指定の値を突っこむ(SQLServer)の方法などで、IDENTITY指定されていても連番にすることはできるのですが。。。

といってもロールバックするケースというのは稀だし、型としてはintegerなので20億位の数値は作れる。そういう意味では会員のIDなどで利用する範疇では枯渇する可能性は低いのですが、なんか空き番があるのは気持ち的に。。。
連番に空きを作りたくない。という場合は、自力でなんらか実装するのがよいって事なんでしょうかねぇ。

2009年8月15日土曜日

[SQL]TOPの件数指定

SQLServer2000までは、変数にてTOPの件数を指定できなかったのですが、2005以降は指定できるようになっていました。ってことを先日発見しました。備忘録代わりにメモ。

DECLARE @CNT int
SET @CNT = 100
SELECT top (@CNT) * from xxxx

2009年8月10日月曜日

[.NET]コントロールをビットマップにコピー

ControlにDrawToBitmapというメソッドがあります。このメソッド表示している画像をそのままbitmapに保存することができます。

で、実験してみました。コードはこんな感じ。

/// <summary>
/// ビットマップを取得する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object senderEventArgs e)
{
    int w = this.Size.Width;
    int h = this.Size.Height;
    using (Bitmap bmp = new Bitmap(wh))
    {
        this.DrawToBitmap(bmpthis.Bounds);
        Clipboard.SetImage(bmp);
    }
}


コレを応用すればWebBrowserで適当なサイトを開き画像に保存みたいなことができるじゃなぁい。と思いやってみたのですが、結果は真っ白画像。WebBrowserでは当メソッドの機能が抑止されているようです。
いろんなテクニックを駆使すれば実現できるそうなのですが。。。また今度調べてみようと思います。

2009年8月6日木曜日

[SQL]月末日を取得する(T-SQL)

以前、C#で月末日を取得する方法を紹介しましたが、今回はそれをT-SQLで書いてみました。
コードはこんな感じ。

DECLARE @YYYY char(4);
DECLARE @MM char(2);
DECLARE @RESULT DateTime;

SET @YYYY = '2008';
SET @MM = '2';

--一行で書くとこんなかんじ
--SET @RESULT = DATEADD(day,-1,DATEADD(Month,1,CONVERT(DateTime, @YYYY + '/' + @MM + '/01' ,111)));
--print '@RESULT=' + CONVERT(varchar, @RESULT, 111);

-- 指定月を日付型に
SET @RESULT = CONVERT(DateTime, @YYYY + '/' + @MM + '/01' ,111);
-- +1ヶ月
SET @RESULT = DATEADD(Month,1,@RESULT);
-- -1日
SET @RESULT = DATEADD(day,-1,@RESULT);

print '@RESULT=' + CONVERT(varchar, @RESULT, 111);

2009年8月3日月曜日

[.NET]リパースポイントの判定

先日ディレクトリを再帰的に処理して。。。みたいな処理を書いていたのですが、なぜか特定のディレクトリでスタックオーバーフローが発生していました。
調べてみると、エラーの出るフォルダは、再起するリーパースポイントを設定していることがわかりました。で、リパースポイントを判定する方法を調べてみると、ファイルのアトリビュートから判定可能ということがわかりました。コードはこんな感じ。

if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
{
    //リーパースポイントの場合
}else{
    //リーパースポイント以外の場合
}


ほかにもさまざまな属性が取得できます。詳しくは、FileAttributes 列挙体に一覧が。