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

本文关键字:参数 输出 存储过程 | 更新日期: 2023-09-27 18:36:50

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

在控件离开当前方法之前,必须将 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内对这种情况的优雅处理。

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

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

理由是,如果您将其放在尝试中,则不会发生合理确定的作业。您可以通过在方法前面为其分配默认值(例如,在第一行将其设置为零)来解决此问题。

如果没记错的话,这是因为try的编译方式包括一个内部try,这意味着程序流在继续之前可能无法正确步入try(即使你通常假设try本身不会像if那样中断程序流)。

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

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


记忆确实服务于...语言规范知道一切。

12.3.3.15 尝试-捕获-最终语句(特别是try-catch-finally的赋值分析)。

尝试-捕获-最终语句的确定赋值分析 形式:

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

就好像该语句是包含 尝试捕获语句:

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
    }
}

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

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

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