Oracle:“序列ID_TABLE1.CURRVAL尚未在此会话中定义” - 如何获取序列的最后一个值?

时间:2016-10-03 08:40:23

标签: vb.net oracle

我正在Oracle DB中执行2个INSERT语句。当我的某个文本框在表单上不为空时,第一个INSERT将被保存。仅当Datagridview第一个单元格不为空时,才会保存第二个INSERT。这些表是通过ID_Table1连接的,我使用ID_Table1_seq自动生成新的自动编号。当我尝试保存第二个INSERT时,我收到错误:“序列ID_Table1.CURRVAL尚未在此会话中定义”。第一个INSERT总是完成。我尝试使用“ID_Table1.nextval -1”进行第二次INSERT,但是如果datagridview有更多要保存的记录,则会出现问题 - 生成一个新的序列号。有人能告诉我如何获得序列电流值吗?以下是我尝试过的快照:

    Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click

     OracleConn()'I call this function for connecting to DB

     Using cmd As OracleCommand = New OracleCommand()
           cmd.Connection = OracleConn()
           '/////////I'm adding plenty parameters here/////////
           cmd.CommandText = "INSERT INTO Table1 (ID_Table1, Field1, Field2)
           VALUES(ID_Table1_seq.nextval,: Field1Parameter,: Field2Parameter)" 

        'When Textbox is not empty Execute 1st INSERT and check Datagrid for 2nd INSERT
      If Not MyTxt.Text = "" Then
         cmd.ExecuteNonQuery()
         cmd.CommandText="select last_number from user_sequences where sequence_name='ID_TABLE1_SEQ'"
           For Each row As DataGridViewRow In DataGridView1.Rows
               If row.Cells(0).Value <> Nothing Then

                         '//////Adding plenty parameters here too/////////
                         cmd.CommandText = "INSERT INTO Table2 (ID_Table2, ID_Table1, Field1, Field2) 
                         VALUES (ID_TABLE2_seq.nextval, ID_Table1_seq.currval,: Field1Parameter,: Field2Parameter)"
                         cmd.ExecuteNonQuery()
                    End Using
                Else 'If Datagridview 1st cell empty 
                    Exit For
                End If
            Next
             MsgBox("Saved successfully.", MsgBoxStyle.Information)
       Else
         Exit Sub            
       End If
     End Using

    End Sub

3 个答案:

答案 0 :(得分:0)

您创建了2个不同的连接:

首先

cmd.Connection = OracleConn()
       '/////////I'm adding plenty parameters here/////////
       cmd.CommandText = "INSERT INTO Table1 (ID_Table1, Field1, Field2)
       VALUES(ID_Table1_seq.nextval,: Field1Parameter,: Field2Parameter)"

第二

                     cmd1.Connection = OracleConn()
                     '//////Adding plenty parameters here too/////////

当然在第二次连接中没有人打电话

ID_Table1_seq.next_val

编辑:

   cmd.CommandText = "INSERT INTO Table1 (ID_Table1, Field1, Field2)
           VALUES(ID_Table1_seq.nextval,: Field1Parameter,: Field2Parameter);"
    cmd.ExecuteNonQuery()  // This executes your query

// Set new sql query
cmd.CommandText = "SELECT ID_Table1_seq.currval from dual;"
Dim currentID as Integer = cmd.ExecuteScalar()  // I don't know syntax in vb.net. Just search

答案 1 :(得分:0)

尝试使用此查询:

select last_number from all_sequences where sequence_owner=user and sequence_name='ID_TABLE1_SEQ'

select last_number from user_sequences where sequence_name='ID_TABLE1_SEQ'

<强>编辑: 但是,如果您有多个会话,则可能会出现逻辑错误,例如:

  1. 会话1执行NEXTVAL
  2. 会话2执行NEXTVAL
  3. 会话1选择CURRVAL,它将从会话2 ...
  4. 获取ID

    正确的方法是使用RETURNING INTO子句。

    Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click
    
     OracleConn()'I call this function for connecting to DB
    
     Using cmd As OracleCommand = New OracleCommand()
           cmd.Connection = OracleConn()
           '/////////I'm adding plenty parameters here///////// don't forget to add output parameter CurrID
           cmd.CommandText = "INSERT INTO Table1 (ID_Table1, Field1, Field2)
           VALUES(ID_Table1_seq.nextval,: Field1Parameter,: Field2Parameter)
           RETURNING ID_Table1 INTO :CurrID" 
    
        'When Textbox is not empty Execute 1st INSERT and check Datagrid for 2nd INSERT
      If Not MyTxt.Text = "" Then
         cmd.ExecuteNonQuery()
    
         '///////////get the value of the parameter CurrID
         CurrID = cmd.Parameters[2].value
    
           For Each row As DataGridViewRow In DataGridView1.Rows
               If row.Cells(0).Value <> Nothing Then
    
                         '//////Adding plenty parameters here too///////// don't forget to add parameter ID = CurrID
                         cmd.CommandText = "INSERT INTO Table2 (ID_Table2, ID_Table1, Field1, Field2) 
                         VALUES (ID_TABLE2_seq.nextval, :ID,: Field1Parameter,: Field2Parameter)"
                         cmd.ExecuteNonQuery()
                    End Using
                Else 'If Datagridview 1st cell empty 
                    Exit For
                End If
            Next
             MsgBox("Saved successfully.", MsgBoxStyle.Information)
       Else
         Exit Sub            
       End If
     End Using
    
    End Sub
    

答案 2 :(得分:0)

我终于解决了它。我需要在执行后立即清除所有参数。我还将两个查询组合在同一个连接中:

Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click

     OracleConn()'I call this function for connecting to DB

     Using cmd As OracleCommand = New OracleCommand()
           cmd.Connection = OracleConn()
           '/////////I'm adding plenty parameters here/////////
           cmd.CommandText = "INSERT INTO Table1 (ID_Table1, Field1, Field2)
           VALUES(ID_Table1_seq.nextval,: Field1Parameter,: Field2Parameter)" 

        'When Textbox is not empty Execute 1st INSERT and check Datagrid for 2nd INSERT
      If Not MyTxt.Text = "" Then
         cmd.ExecuteNonQuery()
         cmd.Parameters.Clear()
           For Each row As DataGridViewRow In DataGridView1.Rows
               If row.Cells(0).Value <> Nothing Then

                         '//////Adding plenty parameters here too/////////
                         cmd.CommandText = "INSERT INTO Table2 (ID_Table2, ID_Table1, Field1, Field2) 
                         VALUES (ID_TABLE2_seq.nextval, ID_Table1_seq.currval,: Field1Parameter,: Field2Parameter)"
                         cmd.ExecuteNonQuery()
                         cmd.Parameters.Clear()
                    End Using
                Else 'If Datagridview 1st cell empty 
                    Exit For
                End If
            Next
             MsgBox("Saved successfully.", MsgBoxStyle.Information)
       Else
         Exit Sub            
       End If
     End Using

    End Sub