【问题标题】:Calling an SP using ExecuteNonQuery使用 ExecuteNonQuery 调用 SP
【发布时间】:2018-10-04 16:04:17
【问题描述】:

我的应用中有一些通用代码用于调用插入等非查询命令:

DBComm.CommandText = SQL
DBComm.Connection = Cnn
Ans = DBComm.ExecuteNonQuery

我正在使用它来调用一个接收两个字符串并返回一个 int 的 SP:

Dim SQL As String = "EXEC Import_Validation " & Code & "," & User
Return DbS.Execute(SQL)

这很好用,除了返回值不是 SP 的值(它是某种作业 ID 吗?)。所以我稍微修改了一下:

Param = New SqlParameter("@RETURN_VALUE", SqlDbType.Int)
Param.Direction = ParameterDirection.ReturnValue
DBComm.Parameters.Add(Param)
DBComm.CommandText = SQL
DBComm.Connection = Cnn
DBComm.ExecuteNonQuery

这会运行,但对于 RETURN_VALUE 总是返回 0。我怀疑这是因为我没有以下行:

DBComm.CommandType = CommandType.StoredProcedure

这种怀疑正确吗?

但是,如果我添加此行,SQL 将不再工作,抱怨 Could not find stored procedure "Import_Validation '1234', 'maury'。我认为这是因为它认为我传入的字符串只是名称,并且被参数混淆了。我可以将参数添加为DBComm 上的输入参数,但是该方法将特定于特定的SP。

那么有没有一种方法可以让我使用我构造的 SQL 调用 SP 并仍然返回一个参数?

【问题讨论】:

  • 最好的办法是将命令文本设置为仅过程名称(因此没有 exec)并通过 Parameters.Add 而不是字符串连接添加参数。这修复了您的 SQL 注入漏洞和返回值问题。
  • 确实如此,但现在有问题的代码只能用于具有给定签名的单个 SP。有没有办法写一个通用的版本?
  • ExecuteNonQuery 只返回修改的行。
  • 如果是整数,可以试试 Param.value=cmd.ExecuteScalar()
  • 呸,sql注入孔,烧死我们了!

标签: sql-server vb.net stored-procedures ado.net


【解决方案1】:

如果你只是返回一个整数,我用过这个:

Param.value=cmd.ExecuteScalar() 

【讨论】:

    【解决方案2】:

    我无法猜测也无法解释为什么您在执行存储过程时遇到问题,因为您没有共享完整代码(有问题的代码的完整部分)。但是,一般来说,当您使用ExecuteNonQuery() 时,您应该使用有效的 T-SQL。默认情况下,commandType 是 Text。因此,如果您需要执行存储过程,则需要在执行查询之前将命令类型更改为 StoredProcedure。所以,我想说你的猜测在这一行是正确的:

    DBComm.CommandType = CommandType.StoredProcedure
    

    另外,在您的代码中,您声明了一个@RETURN_VALUE 参数,但我看不到任何调用它的值的东西!?那么,也许这就是问题所在?

    无论如何,检查一下:

    Using connection As New SqlConnection(ConnectionString)
        command As New SqlCommand("dbo.Import_Validation", connection)
        command.CommandType = CommandType.StoredProcedure
    
        command.Parameters.Add("@Code", SqlDbType.VarChar, 250)
        command.Parameters.Add("@User", SqlDbType.VarChar, 250)
        command.Parameters.Add("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue
    
        command.Parameters("@Code").Value = Code
        command.Parameters("@User").Value = User
    
        connection.Open()
        command.ExecuteNonQuery()
    
        'IF returned value is more than one row, then use reader instead
        Dim return_value As Integer = Convert.ToInt32(command.Parameters("@RETURN_VALUE").Value)
    
        connection.Close()
    End Using 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多