10

出力パラメータとして文字列を取得していますが、AddOutParameter の呼び出しで Size 引数に何を設定するかを知る必要があります。

int.MaxValue のような巨大な数値を使用できることはわかっていますが、ベスト プラクティスを知りたいです。

SQL Server では、列は実際には uniqueidentifier 型です。実行される T-SQL ステートメントは、レコードを挿入し、いくつかの出力変数を、新しく挿入されたレコードの ID と GUID に設定します。これは私が使用している実際のコードですが、変数名が変更されています。

database.AddOutParameter(cmd, "@someInt", DbType.Int32, 0);
database.AddOutParameter(cmd, "@someString", DbType.String, 0);

database.ExecuteNonQuery(cmd);

someInt = (int)database.GetParameterValue(cmd, "@someInt");
someString = database.GetParameterValue(cmd, "@someString").ToString();

実行すると、次のエラーが表示されます...

System.InvalidOperationException: String[2]: Size プロパティのサイズが無効な 0 です。

したがって、文字列出力パラメーターでサイズ 0 を使用できないことは明らかです。Int32 出力パラメーターを使用してそれを行うことができますが、文字列には有効なサイズが必要だと思います。では、サイズを設定するためのベストプラクティスは何ですか? パフォーマンスにまったく影響を与えずに巨大なサイズにすることはできますか? int.MaxValue などに設定できますか? ここで使用できる定数はありますか? (String.MaxValue は見当たりませんでした。おそらく、私が C# を初めて使用し、Java のバックグラウンドを持っていることがわかります)。

uniqueidentifier 列の最大サイズを調べて、そのサイズに設定する必要がありますか? VARCHAR または NVARCHAR 列に対して同じことを行っている場合はどうなりますか?

フレームワークが私のためにそれをしてくれることを願っています。出力として取得するすべての文字列のサイズを指定したくありません。ここでベストプラクティスについて何か提案はありますか?

以下の投稿と MSDN のドキュメントを読みましたが、これに対するベスト プラクティスの回答はまだ見つかっていません。

AddOutParameter - DBType.Int32 の長さを見つける非マジック ナンバーの方法

SQL Server から C# への VARBINARY(MAX) の読み取り

4

1 に答える 1

17

UniqueIdentifer に間違ったタイプを使用していることがわかりました。文字列の代わりに使用する必要DbType.Guidがありますが、コメントで答えることができず、確信が持てなかったため、テストする必要があった他の質問がコメントで提起されました。

彼らです

  • さまざまな文字列出力パラメーターのサイズをどのように設定する必要がありますか?
  • それが Nvarchar か varchar かは関係ありますか?
  • 大きすぎたり小さすぎたりするとどうなりますか?

SqlCommandBuilder.DeriveParametersまず、ADO.NET と SQL Server が何をすべきかを調べるために使用し、ストアド プロシージャを実行して戻り値を確認しました。

Sql Type     | DbType                | Size | Returned string.Length()
----------------------------------------------------------------
Varchar(10)  | AnsiString            | 10   | 9
Char(10)     | AnsiStringFixedLength | 10   | 10
Nvarchar(10  | String                | 10   | 9
Varchar(max) | AnsiString            | -1   | 20,480 
NVarchar(max)| String                | -1   | 20,480

予想どおり、派生サイズは、予想される長さの最大値と戻り値を除くすべての文字型の長さフィールドと一致しました。ただし、max 型と DbTypes を見ると、最初の 3 つに関連するいくつかの新しい質問がありました。

  • その AnsiString 型はどうなっているのですか? 代わりに DbType.String に設定すると、同じサイズを維持すると出力に影響しますか? 回答: いいえ、そうではありません。おそらく .NET 文字列が Unicode であるためです。

  • 値を大きくするParamater.Sizeと、最大値以外の値に影響がありますか? 回答: はい、ただし char(10) のみです。空のスペースを追加して出力サイズを増やします。

  • 値を小さくするParamater.Sizeと、最大以外の値に影響がありますか? はい、戻り値を切り捨てます

  • サイズは-1魔法ですか? 回答: はい、サイズを -1 に設定すると、正しく設定したかのように値が返されます。

テスト コード .NET 4.0 SQL Server 2008

SQL コード

CREATE PROCEDURE SomeOutput( 
@tenVC varchar(10)  output,
@tenC char(10) output,
@tenNVC nvarchar(10) output,
@maxVC varchar(max) output,
@maxNVC nvarchar(max) output,
@Indentifier uniqueidentifier output)
AS 


SELECT @tenC = '123456789',
       @tenVC = '123456789',
       @tenNVC = '123456789',
       @Indentifier = NEWID(),
       @maxVC = '',
       @maxNVC = ''



SELECT 
       @maxVC = @maxVC + '1234567890',
       @maxNVC = @maxNVC + '1234567890'
FROM
        master..spt_values 
WHERE
      type= 'P'    

C# コード

static void Main(string[] args)
{

    using (SqlConnection cnn = new SqlConnection("Server=.;Database=Test;Trusted_Connection=True;"))
    {
        SqlCommand cmd = new SqlCommand("SomeOutput", cnn);
        cmd.CommandType = CommandType.StoredProcedure;
        cnn.Open();
        SqlCommandBuilder.DeriveParameters(cmd);

        Printparams(cmd.Parameters, "Derived");

        foreach (SqlParameter param in cmd.Parameters)
        {
            //By default output parameters are InputOutput
            //This will cause problems if the value is both null
            if (param.Direction == ParameterDirection.InputOutput )
                param.Direction = ParameterDirection.Output;

        }


        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters ,"Executed");


        cmd.Parameters["@tenVC"].DbType = DbType.String;
        cmd.Parameters["@tenNVC"].DbType = DbType.AnsiString;

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "DbType change");



        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32
                && param.DbType != DbType.Guid
                && param.Size != -1)
            {
                param.Size = param.Size * 2;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Mangeled sizes up");


        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32 
                && param.DbType != DbType.Guid
                && param.Size != -1)
            {
                param.Size = param.Size / 4;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Mangeled sizes down");

        cmd.Parameters["@maxVC"].Size = Int32.MaxValue;
        cmd.Parameters["@maxNVC"].Size = Int32.MaxValue;

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Fixed max sizes");

        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32
                && param.DbType != DbType.Guid)
            {
                param.Size = -1;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "is negative one magic");

        }
}

出力

Derived
@RETURN_VALUE : Int32 : 0 : ReturnValue : 0 :
@tenVC : AnsiString : 10 : InputOutput : 0 :
@tenC : AnsiStringFixedLength : 10 : InputOutput : 0 :
@tenNVC : String : 10 : InputOutput : 0 :
@maxVC : AnsiString : -1 : InputOutput : 0 :
@maxNVC : String : -1 : InputOutput : 0 :
@Indentifier : Guid : 0 : InputOutput : 0 :

Executed
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : AnsiString : 10 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 10 : Output : 10 : 123456789
@tenNVC : String : 10 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : eccc3632-4d38-44e8-9edf-031

DbType change
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 10 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 10 : Output : 10 : 123456789
@tenNVC : AnsiString : 10 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 94cb0039-8587-4357-88fb-25c

Mangeled sizes up
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 20 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 20 : Output : 20 : 123456789
@tenNVC : AnsiString : 20 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 4de88f14-9963-4a78-b09b-bb6

Mangeled sizes down
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 5 : Output : 5 : 12345
@tenC : AnsiStringFixedLength : 5 : Output : 5 : 12345
@tenNVC : AnsiString : 5 : Output : 5 : 12345
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 5e973e72-14e5-4b75-9cff-e88

Fixed max sizes
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 5 : Output : 5 : 12345
@tenC : AnsiStringFixedLength : 5 : Output : 5 : 12345
@tenNVC : AnsiString : 5 : Output : 5 : 12345
@maxVC : AnsiString : 2147483647 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : 2147483647 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 6cab2b41-d4ba-42d2-a93a-e59

is negative one magic
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : -1 : Output : 9 : 123456789
@tenC : AnsiString : -1 : Output : 10 : 123456789
@tenNVC : AnsiString : -1 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 0d69ed57-fab7-49c8-b03a-d75
于 2012-06-01T21:57:43.073 に答える