返回字符串时,在Database.AddOutParameter中使用Size参数的内容是什么?

Jim*_*Jim 9 .net c# database sql-server enterprise-library

我得到一个字符串作为输出参数,并需要知道在调用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();
Run Code Online (Sandbox Code Playgroud)

执行时,我收到以下错误...

System.InvalidOperationException:String [2]:Size属性的大小无效.

所以对我来说很明显,你不能只使用带字符串输出参数的0大小.你可以用Int32输出参数做到这一点,但我猜一个字符串需要一个有效的大小.那么设置尺寸的最佳做法是什么?它可以只是一个巨大的尺寸而不会影响性能吗?我可以将它设置为int.MaxValue或其他什么?这里可以使用任何常量; (没有看到任何String.MaxValue - 你可能会说我是C#的新手,有Java背景).

我应该找出uniqueidentifier列的最大大小,并将大小设置为该值吗?如果我为VARCHAR或NVARCHAR列做同样的事情呢?

我希望框架能够为我做这件事; 我不想为输出的每个字符串指定一个大小.任何人都有任何建议,以获得最佳实践?

我已经阅读了下面的帖子以及MSDN文档,但我还没有找到最佳实践答案.

AddOutParameter - 查找DBType.Int32长度的非魔数方式

从SQL Server读取VARBINARY(MAX)到C#

Con*_*rix 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
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,派生大小匹配所有字符类型的长度字段,除了max和返回值,其中预期长度.然而,看看最大类型和DbTypes,我们在前三个问题上有了一些新的问题.

  • 这是怎么回事与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'    
Run Code Online (Sandbox Code Playgroud)

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");

        }
}
Run Code Online (Sandbox Code Playgroud)

输出

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
Run Code Online (Sandbox Code Playgroud)