从存储过程放置输出参数解析

时间:2012-06-12 11:55:56

标签: c# visual-studio-2008

由于输出存储过程参数的解析明显错位,我遇到了这个错误。

  

在控制离开当前方法之前必须将out参数'whichID'分配给

代码:

public static bool CreateFilmTest(string param1, string param2, out int whichID)
{
            DbCommand com = GenericDataAccess.CreateCommand();
            com.CommandText = "CatalogCreateFilmTest";

            DbParameter param = com.CreateParameter();
            param.ParameterName = "@param1";
            param.Value = param1;
            param.DbType = DbType.String;
            param.Size = 200;
            com.Parameters.Add(param);
            ..........            
            param = com.CreateParameter();
            param.ParameterName = "@Fid";
            param.Direction = ParameterDirection.Output;
            param.DbType = DbType.Int32;
            com.Parameters.Add(param);

            int result = -1;

            try
            {
                result = GenericDataAccess.ExecuteNonQuery(com);

                whichID = Int32.Parse(com.Parameters["@Fid"].Value.ToString());

            }
            catch
            {
                // ....
            }


           return (result >= 1);
}

如果我放置:whichID = Int32.Parse(com.Parameters["@Fid"].Value.ToString()); 在返回行之前的行,该方法成功执行并提供正确的结果。

但是,如果我将它放在try括号中,它会给出开头提到的错误。

为什么会这样?

我的第一个选择是将放在try括号中,因为IF因任何原因导致ExecuteNonQuery失败,处理其输出参数(whichID没有意义})。因此,我认为最好将两个元素(程序的执行和来自过程的输出参数的处理)耦合到try块中,在错误的情况下触发catch内的这种情况的优雅处理。

非常感谢您的意见。谢谢。安娜

3 个答案:

答案 0 :(得分:1)

理由是,如果您将其放在try中,则没有合理确定的任务发生。您可以通过在方法前面为其指定默认值来解决此问题(例如,在第一行将其设置为零)。

答案 1 :(得分:1)

如果内存服务这是因为try的编译方式是包含内部try,这意味着在继续执行之前程序流可能无法正确地进入try向前(即使您通常认为try本身并不会中断程序流,例如if

然后,这将在退出方法之前触发编译器检查被分配的out参数。

只需在方法的最顶部默认值即可。

<小时/> 记忆确实起作用......语言规范知道所有。

12.3.3.15 Try-catch-finally statements(特别是try-catch-finally的分配分析)。

  

对try-catch-finally语句的明确赋值分析   形式:

try [try-block]
catch ( … ) [catch-block-1]
…
catch ( … ) [catch-block-n]
finally [finally-block]
     完成

就好像该语句是一个包含a的try-finally语句   try-catch语句:

try {
try [try-block]
catch ( … ) [catch-block-1]
…
catch ( … ) [catch-block-n]
}
finally [finally-block]

一个例子:

class A
{
    static void F() {
        int i, j;
        try {
            goto LABEL;
            // neither i nor j definitely assigned
            i = 1;
            // i definitely assigned
        }
        catch {
            // neither i nor j definitely assigned
            i = 3;
            // i definitely assigned
        }
        finally {
            // neither i nor j definitely assigned
            j = 5;
            // j definitely assigned
        }
        // i and j definitely assigned
        LABEL:;
        // j definitely assigned
    }
}

答案 2 :(得分:0)

您得到该错误的原因是由于编译器处理try / catch的方式。 try / catch块在某种意义上是条件语句。其中的代码仅在它之前的代码没有抛出异常时才会出现,并且代码本身只有在它本身不抛出异常时才完成执行。

如果您只是在try中定义变量(或仅在catch(es)中),那么您无法确定这些代码行是否会运行。如果您的变量仅在try-block中定义,那么如果之前存在异常,或者在执行定义的行上,则可能会跳过该变量。如果您的变量仅在catch子句中定义,那么如果没有异常发生,它将被跳过。

最好在进入try-catch块之前声明默认值,或在catch子句中声明失败值。