【问题标题】:Why the output parameter of my ADODB.Command does not retrieve a value when executing?为什么我的 ADODB.Command 的输出参数在执行时没有检索到值?
【发布时间】:2023-03-31 03:54:01
【问题描述】:

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

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

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

【问题讨论】:

  • 对于像单个字符值这样简单的东西(无论如何它恰好是数字)为什么不在存储过程中使用RETURN 1,那么你可以使用adParamReturnValueParameterDirectionEnum未被ADODB.Recordset 调用阻止。

标签: sql-server stored-procedures asp-classic odbc ado


【解决方案1】:

由于@diana 具有already pointed out,因此您无法访问输出参数,因为在执行查询之前不会设置它。

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

乍一看似乎是这样,但当你考虑到使用

Select @msg_salida = '1'

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

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

例如通过将上面的行更改为

SET @msg_salida = '1'

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

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

【讨论】:

  • 谢谢! SET 和 SELECT 都在过程中工作,但对我来说,这里的关键部分是从 set rds = cmd.Execute 更改为只做 Call cmd.Execute。这使得输出值出现在参数中。好提示!
  • @DanneManne 不客气,因为ADODB.Recordset 会阻止对输出参数的访问,直到它被关闭。
【解决方案2】:

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

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

do until rs.EOF
     rs.MoveNext
loop

【讨论】:

  • 或者使用rs.GetRows()返回一个数组,然后关闭ADODB.Recordset对象。这样,无论您是否需要访问输出参数,您的数组都可以迭代。
  • 虽然the answer you link 是正确的,但他们没有解释原因,并让您看起来好像在迭代所有记录集之前永远无法访问OUTPUT 参数。这根本不是真的,我将在这个问题上添加我自己的答案来解释这一点。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 2019-12-21
    相关资源
    最近更新 更多