- 3,715,830 Users
- 2,242,890 Discussions
- 7,845,632 Comments
Forum Stats
Discussions
Categories
- 17 Data
- 362.2K Big Data Appliance
- 7 Data Science
- 1.6K Databases
- 472 General Database Discussions
- 3.7K Java and JavaScript in the Database
- 22 Multilingual Engine
- 487 MySQL Community Space
- 5 NoSQL Database
- 7.6K Oracle Database Express Edition (XE)
- 2.8K ORDS, SODA & JSON in the Database
- 417 SQLcl
- 42 SQL Developer Data Modeler
- 184.9K SQL & PL/SQL
- 21K SQL Developer
- 1.9K Development
- 3 Developer Projects
- 32 Programming Languages
- 135.1K Development Tools
- 9 DevOps
- 3K QA/Testing
- 254 Java
- 6 Java Learning Subscription
- 10 Database Connectivity
- 66 Java Community Process
- 1 Java 25
- 9 Java APIs
- 141.1K Java Development Tools
- 6 Java EE (Java Enterprise Edition)
- 153K Java Essentials
- 135 Java 8 Questions
- 86.2K Java Programming
- 270 Java Lambda MOOC
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 10 Java SE
- 13.8K Java Security
- 3 Java User Groups
- 22 JavaScript - Nashorn
- 18 Programs
- 125 LiveLabs
- 30 Workshops
- 9 Software
- 3 Berkeley DB Family
- 3.5K JHeadstart
- 5.7K Other Languages
- 2.3K Chinese
- 3 Deutsche Oracle Community
- 11 Español
- 1.9K Japanese
- 2 Portuguese
Concurrency violation: the UpdateCommand affected 0 records.
If changing ename in datagrid and try to update error occurs:
"Concurrency violation: the UpdateCommand affected 0 records."
With OleDbDataAdapter and MSORA works well.
Is it a Beta issues?
Public Class FormTest
Inherits System.Windows.Forms.Form
Dim con As Oracle.DataAccess.Client.OraConnection
Dim cmd As Oracle.DataAccess.Client.OraCommand
Dim da As Oracle.DataAccess.Client.OraDataAdapter
Dim cb As Oracle.DataAccess.Client.OraCommandBuilder
Dim ds As DataSet
#Region " Vom Windows Form Designer generierter Code "
Public Sub New()
MyBase.New()
' Dieser Aufruf ist f|r den Windows Form-Designer erforderlich.
InitializeComponent()
' Initialisierungen nach dem Aufruf InitializeComponent() hinzuf|gen
End Sub
' Die Form |berschreibt den Lvschvorgang der Basisklasse, um Komponenten zu bereinigen.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' F|r Windows Form-Designer erforderlich
Private components As System.ComponentModel.IContainer
'HINWEIS: Die folgende Prozedur ist f|r den Windows Form-Designer erforderlich
'Sie kann mit dem Windows Form-Designer modifiziert werden.
'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
Friend WithEvents ButtonFill As System.Windows.Forms.Button
Friend WithEvents ButtonUpdate As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ButtonFill = New System.Windows.Forms.Button()
Me.DataGrid1 = New System.Windows.Forms.DataGrid()
Me.ButtonUpdate = New System.Windows.Forms.Button()
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'ButtonFill
'
Me.ButtonFill.Location = New System.Drawing.Point(320, 16)
Me.ButtonFill.Name = "ButtonFill"
Me.ButtonFill.Size = New System.Drawing.Size(112, 32)
Me.ButtonFill.TabIndex = 0
Me.ButtonFill.Text = "Fill"
'
'DataGrid1
'
Me.DataGrid1.CaptionText = "Test Datenzugriff"
Me.DataGrid1.DataMember = ""
Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.DataGrid1.Location = New System.Drawing.Point(8, 64)
Me.DataGrid1.Name = "DataGrid1"
Me.DataGrid1.Size = New System.Drawing.Size(544, 344)
Me.DataGrid1.TabIndex = 1
'
'ButtonUpdate
'
Me.ButtonUpdate.Location = New System.Drawing.Point(440, 16)
Me.ButtonUpdate.Name = "ButtonUpdate"
Me.ButtonUpdate.Size = New System.Drawing.Size(112, 32)
Me.ButtonUpdate.TabIndex = 2
Me.ButtonUpdate.Text = "Update"
'
'FormTest
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(560, 413)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.ButtonUpdate, Me.DataGrid1, Me.ButtonFill})
Me.Name = "FormTest"
Me.Text = "FormTest"
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub ButtonFill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFill.Click
' Connect
Try
con = New Oracle.DataAccess.Client.OraConnection( _
"User Id=scott;Password=tiger;Data Source=MTV_np")
con.Open()
' Create the OraCommand
cmd = New Oracle.DataAccess.Client.OraCommand("select * from emp")
cmd.Connection = con
cmd.CommandType = CommandType.Text
' Create the OraDataAdapter
da = New Oracle.DataAccess.Client.OraDataAdapter(cmd)
' Create the OraCommandBuilder
cb = New Oracle.DataAccess.Client.OraCommandBuilder(da)
da.InsertCommand = cb.GetInsertCommand
da.UpdateCommand = cb.GetUpdateCommand
da.DeleteCommand = cb.GetDeleteCommand
' Populate a DataSet
ds = New DataSet()
da.FillSchema(ds, SchemaType.Source)
da.Fill(ds)
Me.DataGrid1.DataSource = ds
Me.DataGrid1.DataMember = "Table"
Catch ee As Exception
MessageBox.Show(ee.Message)
End Try
End Sub
Private Sub ButtonUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUpdate.Click
Try
da.Update(ds, "Table")
Catch ee As Exception
MessageBox.Show(ee.Message)
End Try
End Sub
End Class
"Concurrency violation: the UpdateCommand affected 0 records."
With OleDbDataAdapter and MSORA works well.
Is it a Beta issues?
Public Class FormTest
Inherits System.Windows.Forms.Form
Dim con As Oracle.DataAccess.Client.OraConnection
Dim cmd As Oracle.DataAccess.Client.OraCommand
Dim da As Oracle.DataAccess.Client.OraDataAdapter
Dim cb As Oracle.DataAccess.Client.OraCommandBuilder
Dim ds As DataSet
#Region " Vom Windows Form Designer generierter Code "
Public Sub New()
MyBase.New()
' Dieser Aufruf ist f|r den Windows Form-Designer erforderlich.
InitializeComponent()
' Initialisierungen nach dem Aufruf InitializeComponent() hinzuf|gen
End Sub
' Die Form |berschreibt den Lvschvorgang der Basisklasse, um Komponenten zu bereinigen.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' F|r Windows Form-Designer erforderlich
Private components As System.ComponentModel.IContainer
'HINWEIS: Die folgende Prozedur ist f|r den Windows Form-Designer erforderlich
'Sie kann mit dem Windows Form-Designer modifiziert werden.
'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
Friend WithEvents ButtonFill As System.Windows.Forms.Button
Friend WithEvents ButtonUpdate As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ButtonFill = New System.Windows.Forms.Button()
Me.DataGrid1 = New System.Windows.Forms.DataGrid()
Me.ButtonUpdate = New System.Windows.Forms.Button()
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'ButtonFill
'
Me.ButtonFill.Location = New System.Drawing.Point(320, 16)
Me.ButtonFill.Name = "ButtonFill"
Me.ButtonFill.Size = New System.Drawing.Size(112, 32)
Me.ButtonFill.TabIndex = 0
Me.ButtonFill.Text = "Fill"
'
'DataGrid1
'
Me.DataGrid1.CaptionText = "Test Datenzugriff"
Me.DataGrid1.DataMember = ""
Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.DataGrid1.Location = New System.Drawing.Point(8, 64)
Me.DataGrid1.Name = "DataGrid1"
Me.DataGrid1.Size = New System.Drawing.Size(544, 344)
Me.DataGrid1.TabIndex = 1
'
'ButtonUpdate
'
Me.ButtonUpdate.Location = New System.Drawing.Point(440, 16)
Me.ButtonUpdate.Name = "ButtonUpdate"
Me.ButtonUpdate.Size = New System.Drawing.Size(112, 32)
Me.ButtonUpdate.TabIndex = 2
Me.ButtonUpdate.Text = "Update"
'
'FormTest
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(560, 413)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.ButtonUpdate, Me.DataGrid1, Me.ButtonFill})
Me.Name = "FormTest"
Me.Text = "FormTest"
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub ButtonFill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFill.Click
' Connect
Try
con = New Oracle.DataAccess.Client.OraConnection( _
"User Id=scott;Password=tiger;Data Source=MTV_np")
con.Open()
' Create the OraCommand
cmd = New Oracle.DataAccess.Client.OraCommand("select * from emp")
cmd.Connection = con
cmd.CommandType = CommandType.Text
' Create the OraDataAdapter
da = New Oracle.DataAccess.Client.OraDataAdapter(cmd)
' Create the OraCommandBuilder
cb = New Oracle.DataAccess.Client.OraCommandBuilder(da)
da.InsertCommand = cb.GetInsertCommand
da.UpdateCommand = cb.GetUpdateCommand
da.DeleteCommand = cb.GetDeleteCommand
' Populate a DataSet
ds = New DataSet()
da.FillSchema(ds, SchemaType.Source)
da.Fill(ds)
Me.DataGrid1.DataSource = ds
Me.DataGrid1.DataMember = "Table"
Catch ee As Exception
MessageBox.Show(ee.Message)
End Try
End Sub
Private Sub ButtonUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUpdate.Click
Try
da.Update(ds, "Table")
Catch ee As Exception
MessageBox.Show(ee.Message)
End Try
End Sub
End Class
Comments
-
Jens,
This is a problem with ODP.NET. This issue will be fixed in the next Beta release of ODP.NET. In the meantime, a workaround would be to NOT set the individual OraDataAdapter commands (InsertCommand, UpdateCommand, and DeleteCommand) with the SQL generated by the OraCommandBuilder. Generally speaking (in ADO.NET terms), if the command properties are not set and the OraCommandBuilder is instantiated for a data adapter, invoking .Update on the dataadapter will automatically utilize the SQL generated by the commandbuilder since the "custom SQL" is not provided by the application. Essentially, leaving the dataadapter commands to null and associating the commandbuilder to the dataadapter enables "auto-SQL generation."
There's actually a benefit ODP.NET provides in leaving the command properties of the OraDataAdapter to null. For example, an UPDATE statement actually requires only the modified column data in the SET clause. Therefore, ODP.NET does not bind unmodified column data in the SET clause of an UPDATE SQL. (The WHERE clause will of course contain all the columns in the datatable (except for non-scalar data) to avoid dirty writes.) This approach can provide better performance if there are some large scalar data in the DataTable that are not modified. In other words, the OraDataAdapter does not use the public Get(Insert/Update/Delete)Command() methods when OraDataAdapter.Update() is called. Instead, OraDataAdapter uses an internal function which builds an optimized UPDATE SQL for that row that only binds the updated column data in the SET clause.
If you use the public Get(Insert/Update/Delete)Command() method explicitly as in your application, the OraCommandBuilder will generate the UPDATE SQL which sets every column in the datatable since it has to be generic enough to update any row in the DataTable. Therefore, your application is NOT actually using the enhanced functionality of "auto-generated command" that ODP.NET provides. Instead, the application is using the generated SQL as a "Custom SQL".
thanks,
nari.
This discussion has been closed.