INSERT和SELECT语句的组合会导致VB出错

时间:2015-03-26 03:48:10

标签: sql sql-server vb.net recordset

这是我的SQL Server存储过程

ALTER PROC [dbo].[insRequestVote]  
     @fkRequest     int,  
     @fkOrganisation    int,  
     @fkUser            int  
AS 
   IF NOT Exists(SELECT 1 FROM [dbo].[tblRequestVote] 
                 WHERE [fkRequest] = @fkRequest 
                   AND [fkOrganisation] = @fkOrganisation 
                   AND [fkUser] = @fkUser)
   BEGIN
       /* This user from this organisation has not yet voted for this request */ 
       INSERT INTO [dbo].[tblRequestVote] ([fkRequest], [fkOrganisation],[fkUser], [DateStamp])
       VALUES (@fkRequest, @fkOrganisation, @fkUser, GetDate());

       SELECT 
           'Inserted' AS VoteResult;
   END
   ELSE
      SELECT 'You have already voted for this SR' AS VoteResult;

当我在T-SQL中运行它时,它可以很好地工作,例如

insRequestVote 1, 4, 23 

将返回所需的短语。但是,当我从VB.NET调用存储过程时,它只将记录写入表中,但不返回该短语。

代码背后:

Dim ADOConn As New ADODB.Connection  
ADOConn.ConnectionString = WFConnectionString  
If (ADOConn.State <> ConnectionState.Open) Then ADOConn.Open()  
Dim ADORecSet As New ADODB.Recordset  
Dim sSql As String = ""  

Try  
    '----// Save the Vote for the SR  
    sSql = "dbo.insRequestVote " & row.Cells(0).Text & "," & row.Cells(1).Text & "," & row.Cells(2).Text
    ADORecSet = ADOConn.Execute(sSql)  

   If Not ADORecSet.EOF Then  
      If ADORecSet.Fields("VoteResult").Value = "Inserted" Then  
         gridSRs.DataBind()  
         row.Cells(4).Text = "1"  
      End If  
   End If  

   ADORecSet.Close()  
Catch GenEx As Exception  
   '----- Catch-all  
   LogAction(Session("WhoAmI"), GenEx.Message, "Error")  
Finally  
   ADOConn.Close()  
   ADOConn = Nothing  
End Try  

这一切都可以正常工作到“If Not ADORecSet.EOF Then”语句,它会跳转到异常行。

是异常消息
  

关闭对象时不允许操作。

我的问题是:为什么特定模式在所有情况下都有效,除非我在一个存储过程中组合了INSERT和SELECT?

2 个答案:

答案 0 :(得分:2)

我们从哪里开始......你的代码充斥着反模式。你应该阅读ado的正确使用,我们转向更简单的ORM。除此之外:

  1. 从不动态构建一个字符串,以便在用户输入的SQL中执行。始终始终使用参数化查询。否则,我可以从你的文本框中删除所有的数据库表,这很简单。

  2. 由于这是一个存储过程,您应该将命令类型设置为该命令,而不是使用文本。否则,这会导致返回值出现奇怪现象,这是不好的做法。

  3. 您将此标记为vb。网但您使用的是旧版ADO?使用ADO。返回数据集的Net,而不是已弃用的记录集

答案 1 :(得分:-1)

知道了!以防其他人正在尝试这个,这是我修改过的代码:

Dim SQLConn As New SqlConnection(WFConnectionStringNET)
If (SQLConn.State <> ConnectionState.Open) Then SQLConn.Open()

Dim sSql As String = ""
Try
                '----// Save the Vote for the SR
                sSql = "dbo.insRequestVote " & Mid(row.Cells(0).Text, 2, InStr(row.Cells(0).Text, ":") - 2) & "," &
                                               Session("ThisUserOrganisationID") & "," &
                                               Session("ThisUserID")
                Dim sqlCmd As New SqlCommand(sSql, SQLConn)
                sqlCmd.Parameters.Add("@fkRequest", SqlDbType.Int).Value = Mid(row.Cells(0).Text, 2, InStr(row.Cells(0).Text, ":") - 2)
                sqlCmd.Parameters.Add("@fkOrganisation", SqlDbType.Int).Value = Session("ThisUserOrganisationID")
                sqlCmd.Parameters.Add("@fkUser", SqlDbType.Int).Value = Session("ThisUserID")
                Dim sqlDR As SqlDataReader = sqlCmd.ExecuteReader()

                While sqlDR.Read()
                    If sqlDR("VoteResult") = "Inserted" Then
                        gridSRs.DataBind()
                        row.Cells(4).Text = "1"
                    End If
                End While
                sqlDR.Close()

                LogAction(Session("WhoAmI"), "Voted for SR " & row.Cells(5).Text)

            Catch GenEx As Exception
                '-----// Catch-all
                LogAction(Session("WhoAmI"), GenEx.Message, "Error")
            Finally
                SQLConn.Close()
                SQLConn = Nothing
            End Try