none
パラメータのサイズってなんでしょうか? RRS feed

  • 質問

  • お世話になります。

    Parameter にはサイズがありますが、このサイズはデータ型などによって違ってくると思うのですが、どう設定したらよいのでしょうか?

    具体的には、SqlParameter を

    cmd.Parameters.Add("@品名", SqlDbType.Text, 50, "品名");

    などとするときの、この50 のことです。

    SqlDbType.Text であれば、文字列のサイズだと分かるのですが、その他の型のときにはどう考えたらよいのか分かりません。

    ぜひ、お聞かせ願えませんでしょうか?よろしくお願いいたします。

    2010年5月4日 13:11

回答

  • ソース列を指定できるAddメソッドのオーバーロードでは、同時にサイズパラメータを指定することが必須ですので、何らかのサイズを必ず指定しなければなりません。SqlDbType.Intの場合は4で正解ですが、どのみち無視されますので、例えば0でもかまいません。では一般的にどう書くのかというのはたぶん無くて、それぞれのポリシーの問題だと思います。

    一方、K. Takaokaさんも書かれていますが、サイズのパラメータが無いAddメソッドのオーバーロードを使い、その上でSqlParameterのSourceColumnプロパティを設定する方法も考えられます。しかし、この方法は上記に比べてコードが冗長になりますので、積極的にお勧めというわけでもありません。やはりポリシーによると思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク yasheeki 2010年5月7日 13:08
    2010年5月6日 14:54
    モデレータ

すべての返信

  • リファレンスにも、

    > Size プロパティは、バイナリ型と文字列型で使用します。 
    > 
    > 文字列以外のデータ型および ANSI 文字列データでは、Size プロパティは、バイト数を示します。Unicode 文字列データでは、Size は、文字数を示します。文字列の文字数に、終端文字は含まれません。 
    > 可変長データ型では、Size は、サーバーに送信するデータの最大量を示します。たとえば、Unicode 文字列の場合、Size を使用して、サーバーに送信されるデータ量を先頭から 100 文字までに制限できます。 

    とありますし、そのまま文字数またはバイト数であると考えてよいのではないかと思います。それ以外の型を使用するときは、サイズ指定が不要な Add() のオーバーロードを使ってパラメータを登録すればよろしいかと思います。

    2010年5月5日 0:51
  • ご返信ありがとうございます。

    文字列型のときはバイト数や、文字数を表すことが分かったのですが、

    datetime型や、int型や、boolean型などのとき、たとえば1000億までの数値まで受け入れられるようにしたい、といった場合にはどうしたらよいのでしょうか?

    この辺が、自分では曖昧なまま、勝手に4だの10だのといった、根拠のない数値を入れていました。この効果がどうなるか分からないままのコードなので、不安が募ります。

    よろしくお願いします。

    2010年5月5日 14:22
  • 以下に記述されている通り、固定サイズであればsizeプロパティは無視されます。datetimeやintも固定長と分類されるのだと思います。

    Size プロパティ
    http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlparameter.size.aspx

    このsizeプロパティはデータベースへ格納できるサイズを指定するのではありません。SqlParameterが扱えるサイズを明確に定義するためのものです。つまりSqlParameterというオブジェクトの一つの情報に過ぎません。例えばストアドプロシージャの入力パラメータの定義がnvarchar(10)であれば、最大で10文字までしかそのパラメータに与えてはいけませんが、その最大10文字というサイズ制限をSqlParameterに付加するのがsizeプロパティの役目です。
    intなどの固定長の場合はsizeプロパティが指定されなくてもSqlParameterが扱えるサイズは明確に決定されますから、sizeプロパティは必要なく、結果として無視されるのでしょう。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2010年5月5日 15:45
    モデレータ
  • ご回答ありがとうございます。

    固定サイズであればsizeプロパティは無視されますということは、

    cmd.Parameters.Add("@Amount", SqlDbType.Int, 4, "Amount");

    のようなとき、この4という部分は、どう書き変えたら望ましいのでしょうか?あるいは、一般にはどうすべきでしょうか?

    よろしくお願いします。

    2010年5月6日 11:08
  • 最初の投稿にも書いていますが、

    cmd.Parameters.Add("@Amount", SqlDbType.Int);

    と、引数の少ないオーバーロードを使用してください。ソース列名を指定したいのであれば、

    cmd.parameters.Add(new SqlParameter()
    {
      ParameterName = "@Amount",
      DbType = SqlDbType.Int,
      SourceColumn = "amount",
    });
    

    といったかんじにするのも、1つの手です。

    2010年5月6日 14:44
  • ソース列を指定できるAddメソッドのオーバーロードでは、同時にサイズパラメータを指定することが必須ですので、何らかのサイズを必ず指定しなければなりません。SqlDbType.Intの場合は4で正解ですが、どのみち無視されますので、例えば0でもかまいません。では一般的にどう書くのかというのはたぶん無くて、それぞれのポリシーの問題だと思います。

    一方、K. Takaokaさんも書かれていますが、サイズのパラメータが無いAddメソッドのオーバーロードを使い、その上でSqlParameterのSourceColumnプロパティを設定する方法も考えられます。しかし、この方法は上記に比べてコードが冗長になりますので、積極的にお勧めというわけでもありません。やはりポリシーによると思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク yasheeki 2010年5月7日 13:08
    2010年5月6日 14:54
    モデレータ
  • K.Takaoka さま、trapemiya さま

    ご回答ありがとうございます。

    こんな所に、個人的には曖昧と思えるものがあったとは、完成度の点で疑問に思ってしまうのは間違いでしょうか?

    でも、これで安心しました。助かります。

    2010年5月7日 13:13
  • すでに解決済みのようですが・・・

    > 固定サイズであればsizeプロパティは無視されますということは、
    >
    > cmd.Parameters.Add("@Amount", SqlDbType.Int, 4, "Amount");
    >
    > のようなとき、この4という部分は、どう書き変えたら望ましいの
    > でしょうか?あるいは、一般にはどうすべきでしょうか?

    個人的には、特に必要がない限り 0 に統一しておくのがよいと思い
    ます。そう決めておけば、0 以外の数字が入っている時はそれなりの
    意味がある(設定する必要がある)ということがすぐ分かりますし。

    バイト数が分からなければわざわざ調べて、無視されるので意味のな
    い情報を書いて、場合によっては間違えた値を書いたりして、必要が
    ある場合と見分けがつかなくなったりして・・・というのは、どう考
    えても面白くないです。

    ちなみに、自動生成される TableAdapter の中では、可変長データ型
    のデータも含めてすべて 0 が使われています。(Microsoft のポリ
    シー?)

    MSDN ライブラリには「可変長データ型では、Size は、サーバーに送
    信するデータの最大量を示します。」とありますが、0 の場合は制限
    しないようです。0 以外の数字を入れると制限します。

    2010年5月7日 13:24