くりーむわーかー

プログラムとか。作ってて ・試しててハマった事など。誰かのお役に立てば幸いかと。 その他、いろいろエトセトラ。。。

2016年06月

SQLServer 2000 ストアドとかの更新日

持ってないんだって・・・。

SQLServer2005以降なら、sys.objectsの「modify_date」で取れるんだけど、SQLServer2000は更新日が無いらしい。衝撃的である。

ストアド、関数、ビューのソース管理するツールをふんわり作ってるんだけど、古い環境だと、SQLServer2000をいまだに使ってやがる環境がまだあるもんで。。。。

んー、2000の場合はソースのバイナリ比較をするしか無いかしらね。

C# 今さらusingとか

using しないとメモリリークするとか良く分からない思い込みを最近までしていた。単純にリソース(ファイルとか)の解放を楽に書くってのがusingだったのね。

↓で書いた、場合

using (StreamWriter writer = new StreamWriter(Path.Combine(fileFolder, wkFileName), true, sjisEnc))
{
    writer.WriteLine("HOGE FUGA");
}

コンパイラで↓の感じに展開するってだけの話だったのか。

{
    StreamWriter writer = new StreamWriter(Path.Combine(fileFolder, wkFileName), true, sjisEnc);
    try
    {
        writer.WriteLine("HOGE FUGA");
    }
    finally
    {
        if (writer != null)
            ((IDisposable)writer).Dispose();
    }
}

確かに昔(大昔)はfinallyでdispose()呼ぶコード書いてた。それをusingのブロック書くだけで肩代わりするよって話なのね。

てか、 MSDNのココに普通に書いてあるし。やっぱブログとかうだうだ見るよりMSDNを最初に見ないとだめですね。

C# アプリケーションプールのユーザー取得

前から知りたかった。この前見つけたのでメモ。

stringt name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

色々導入してると、アプリケーションプールの実行ユーザー回りで割と落ちることがある。確認できるようにしておきたいのです。IIS見ればいいんだけどさ。。。

いろんなユーザでいんろんなSEが導入してる時とかさ。いろいろあるのよ。いろいろ。

C# シリアライズしたオブジェクトの読み書き

たまに、オブジェクトをバイナリ保存で読み書きしたくなる時がある。いっつも忘れるのでメモメモ。

[Serializable()]
public class HogeClass
{
    public int hogeint { get; set; }
    public string hogestr { get; set; }
    public long hogelong { get; set; }
    public DateTime hogedate { get; set; }
    public byte[] hogebody { get; set; }
}

public class TestClass
{
    //Write
    public static void WriteObj(object InData, out byte[] outBytes)
    {
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            bf.Serialize(ms, InData);
            outBytes= ms.ToArray();
            ms.Close();
        }
    }
    //Read
    public static void ReadObj(byte[] prmBytes, out object OutData)
    {
        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream(prmBytes))
        {
            OutData = bf.Deserialize(ms);
            ms.Close();
        }
    }
    //使用例
    public void test()
    {
        byte[] tmpbytes = null;
        HogeClass wkObj = new HogeClass();
        //Write
        WriteObj(wkObj,out tmpbytes);
        
        Object objdata = new Object();
        //Read
        WriteObj(tmpbytes,out objdata);
        HogeClass wkObj2 = (HogeClass)objdata;
    }
}

Webアプリで全体スクロールをさせないようにする(Jquery使用) その2

以前イベントとかごにょごにょして全体スクロールを止めるものを書いた。

最近、また必要になって、自分で1から作ってる場合はいいんだけど、他のオープンソースのライブラリ使ってる場合に、インベントのバブリングとか追っかけるのが発狂しそうになるので、手っ取り早く無効にする方法。

sample

モーダルウィンドウ(↑の感じのやつ)表示の時に中のコンテンツのスクロールをすると全体スクロールまでいっちゃうのが嫌。すごく嫌。もう一度言うけど、嫌い。

モーダルウィンドウ表示するイベントの処理内で以下を書く。

//スクロールバーごと消す
$("body").css({overflow: "hidden"});

で、だいたい裏の要素クリックでウィンド閉じるとか閉じるボタンで閉じるっていう動きにするのが普通だと思うので、そのイベントで以下を書く。

//スクロールバーを復活させる
$("body").css({overflow: "inherit"});

モーダルウィンドウ表示させてる場合は、これでだいたいうまくいく。

SQLServerで関数とかViewとかストアドのソースを取得

タイトル通り。ググれば出てくるんだけど、イマイチ欲しい情報がすべて乗ってる例がない。なので、特筆。

SELECT
Y.name
,Y.type
,Y.create_date
,Y.modify_date
,X.uses_ansi_nulls
,X.uses_quoted_identifier
,X.definition
FROM sys.sql_modules AS X
INNER JOIN sys.objects AS Y
ON X.object_id = Y.object_id
WHERE Y.is_ms_shipped = 0
ORDER BY Y.type,Y.name

単純に「sys.sql_modules」に「sys.objects」くっつけるだけ。typeとかmodify_dateが欲しいので。 「is_ms_shipped = 0」付けとかないと、SQLServerが勝手に作るやつも出てくる。

SQLServerで列一覧(主キーのフラグ付き)

SQLServerで列の一覧はすぐとれるんだけど、主キーかどうかわからない。なので主キーかどうかのフラグを一緒につけたい場合は↓の感じ。

select 
X.name as tablename
,Y.object_id
,Y.name
,Y.column_id
,Y.system_type_id
,Y.max_length
,Y.is_nullable
,Y.is_identity
,isnull(Z.is_primary_key,0) as is_primary_key
from (
	select * from sys.tables where type = 'U'
) as X
inner join (
	select * from sys.columns
) as Y
on X.object_id = Y.object_id
left join (
	select X.object_id,Y.column_id,Z.is_primary_key from sys.columns as X
	inner join sys.index_columns as Y
	on X.object_id = Y.object_id
	and X.column_id = Y.column_id
	inner join sys.indexes as Z
	on Y.object_id = Z.object_id
	and Y.index_id = Z.index_id
	where Z.is_primary_key = 1
) as Z
on Y.object_id = Z.object_id
and Y.column_id = Z.column_id

もっといい感じに書けると思うけど、ちょっとやっつけ。

EntityFrameworkで属性のテーブル名を取得する

EF使う際に、POCO的なオブジェクトでテーブルの定義を作っておく。↓の感じ

[Table("HOGETABLE")]
public class TestTable
{
    [Key]
    public int HOGETABLEID {get;set;}
    public string 何か { get; set; }
}

テーブル名指定には↑の感じで属性で定義しておく。

で、EFじゃなくて、独自にクエリとか作ったりしたい場合に、これの属性のテーブル名が欲しかったりする。その取り方。

public class TestModel : DbContext
{
    public DbSet<TestTable> TestTables { get; set; }

}

string TableName = "";
using (var context = new TestModel())
{
	foreach (var tmp in context.TestTables.GetType().CustomAttributes)
	{
	    if (tmp.AttributeType.Name == "TableAttribute")//テーブル名を入れてるとこ
	    {
	        TableName = tmp.ConstructorArguments[0].Value.ToString();
	        break;
	    }
	}
}

.NetMVCでWeb.Configの接続文字列をとる

EntityFrameworkを.net MVCで使う場合、Web.Configに↓の感じで接続文字列を設定しておく。

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=***********;Initial Catalog=HOGEDB;Persist Security Info=True; User ID=sa;Password=xxxxxx" providerName="System.Data.SqlClient" />
  </connectionStrings>

で、EFは使い勝手はそこそこいいんだけど、個別にDBにつないで自分でやりたい場合もある。その場合に、この接続文字列を取得したい。やり方は色々あると思うけど、Web。Configの中身を直で持ってくるやり方。

string wkStr = "";
for (int i = 0; i < System.Configuration.ConfigurationManager.ConnectionStrings.Count; i++)
{
    if (System.Configuration.ConfigurationManager.ConnectionStrings[i].Name == "DefaultConnection")
    {
        wkStr = System.Configuration.ConfigurationManager.ConnectionStrings[i].ConnectionString;
        break;
    }
}

設定が複数ある場合もあるので、接続名指定して取得する。色々試してみて、これしかやりようなかった。他に何かいい方法ないかしら。。。

「System.Configuration.ConfigurationManager.ConnectionStringst」ってforeach出来ないのね。Whereとかも使えない。IEnumにどーにかできないものだろうか。

C#でEntityFrameworkはやっぱ遅い?

EF使ってちょろちょろ作ってるけど、発行してるSQLが微妙な感じがたまにする。

特にidentity使ってるテーブルにインサートするとき、インサート文に↓の奴がくっつく。

SELECT ID
FROM [dbo].[TABLENAME]
WHERE @@ROWCOUNT > 0 AND [TABLENAME] = scope_identity()

インサートした直後のidの値をとってるっぽい。インサート後にそのオブジェクトのIDに勝手にID振ってくれてるけど、それようのクエリでしょうね。ただ、クエリとしては遅くないんだけど、プロファイラで見ると、Readsが大きいし、CPUを割とくってる。大量に発行すると致命的な気がするのですが・・・。 インサート直後にそのオブジェクトのID見たいとかあんまりないからなぁ。

んーインサート系は自分でオブジェクトから動的にクエリ作るの作らないとダメかな。

問合せ