为什么我的ADODB.Command的输出参数在执行的时候取不到值?

Why the output parameter of my ADODB.Command does not retrieve a value when executing?

我在 Classic ASP 和 SQL Server 中有一个代码,这个想法很简单,有一个存储过程,所以你可以插入一个文件,但在此之前,sp 会检查是否文件已经存在,之后将 return 一个输出参数,以便我可以在我的 asp 页面上检查它。

问题是输出参数的 returning 值什么都没有,我不知道问题出在哪里..

SP 是:

        ALTER PROCEDURE [dbo].[pi_usu_crear_cuenta]
         @msg_salida    char(1) OUTPUT  /* 0=Registro ya existe, 1=Insert satidfactorio, 2=Update Satidfactorio*/
        ,@usu_email     nvarchar(50)
        ,@usu_alias     nvarchar(50)
        ,@usu_password  nvarchar(50)
        ,@pai_cod       numeric(3,0)
        ,@usu_mayoriaedad char(1)
        ,@pk_pre        int
        ,@usu_respuesta nvarchar(50)

    AS
    BEGIN
        SET NOCOUNT ON;
       IF NOT EXISTS (SELECT * FROM tm_usu_usuarios
                       WHERE usu_email = @usu_email)
       BEGIN
        INSERT INTO tm_usu_usuarios
               (usu_email
               ,usu_alias
               ,usu_password
               ,pai_cod
               ,usu_mayoriaedad
               ,pk_pre
               ,usu_respuesta
               )
         VALUES
               (
                @usu_email
               ,@usu_alias
               ,@usu_password
               ,@pai_cod
               ,@usu_mayoriaedad
               ,@pk_pre
               ,@usu_respuesta
                );
        Select @msg_salida = '1'
       END
   ELSE
   BEGIN
        Select @msg_salida = '2'
   END
    END

经典ASP是:

        Dim cmd2
        Dim Rs_crearcuenta     
        Const adCmdStoredProc = &H0004
        '---- ParameterDirectionEnum Values ----
        Const adParamInput          = &H0001
        Const adParamOutput         = &H0002
        Const adParamReturnValue    = &H0004
        '---- DataTypeEnum Values ----
        Const adInteger     = 3
        Const adChar        = 129
        Const adVarChar     = 200
        Const adVarWChar    = 202
        Const adNumeric     = 131

        Set cmd2 = Server.CreateObject("ADODB.Command")
        Set cmd2.ActiveConnection = Session("Conexion")
        cmd2.CommandText = "pi_usu_crear_cuenta"
        cmd2.CommandType = adCmdStoredProc

        cmd2.Parameters.Append cmd2.CreateParameter("@msg_salida",      adChar,         adParamOutput,      1)      
        cmd2.Parameters.Append cmd2.CreateParameter("@usu_email",       adVarChar,      adParamInput,       50, vEmail)     
        cmd2.Parameters.Append cmd2.CreateParameter("@usu_alias",       adVarChar,      adParamInput,       50, vAlias)     
        cmd2.Parameters.Append cmd2.CreateParameter("@usu_password",    adVarChar,      adParamInput,       50, vPassword)      

        SET param           =  cmd2.CreateParameter("@pai_cod",         adNumeric,      adParamInput,       3, null)
        param.Precision     = 3
        param.NumericScale  = 0
        param.Value         = vPais
        cmd2.Parameters.Append param    'NUMERIC

        cmd2.Parameters.Append cmd2.CreateParameter("@usu_mayoriaedad", adChar,         adParamInput,       1,  vMayoria_edad)      
        cmd2.Parameters.Append cmd2.CreateParameter("@pk_pre",          adInteger,      adParamInput,        ,  vPregunta)      
        cmd2.Parameters.Append cmd2.CreateParameter("@usu_respuesta",   adVarWChar,     adParamInput,       50, vRespuesta)     'NVARCHAR
        cmd2.Prepared = true

        Set Rs_crearcuenta = cmd2.Execute

        vMsgSalida=cmd2.Parameters("@msg_salida").value

        response.write("-")     
        response.write(vMsgSalida)      
        response.write("-")     

        Set Rs_crearcuenta = Nothing
response.end

正如 Why adParamOutput parameter doesn't contain a value after execute 上的回答所解释的那样:

你必须遍历所有记录才能读取输出参数,比如

do until rs.EOF
     rs.MoveNext
loop

因为 @diana has 您无法访问输出参数,因为它在查询执行之前不会设置。

这是一个常见问题,在这种情况下您可能会想,但我没有执行 returns 任何结果的查询,我只是插入一些数据?

乍一看似乎是这种情况,但当您考虑使用

Select @msg_salida = '1'

您实际上返回的是单行单列 ADODB.Recordset 对象。

在这些情况下,建议使用 SET 而不是 SELECT,因为它不会创建 ADODB.Recordset 或阻止对 OUTPUT 参数的访问,直到所有 ADODB.Recordset 对象已关闭。

例如将上面的行更改为

SET @msg_salida = '1'

并将您的 ADODB.Command 执行更改为

'Execute the command without returning any Recordsets
Call cmd2.Execute()

在我的案例中,问题与正在检索的记录集无关。检查是否在经典 ASP 脚本中使用了 On Error Resume Next,因为可能存在 MSSQL 异常被吞没,导致永远无法设置输出参数。