I have been able to recreate the issue. It appears to be an "unfortunate feature" of the Access OLEDB provider when operating on a machine where the Windows system locale does not use the period character (.
) as the decimal symbol.
Using the following code
Dim price As Decimal = Convert.ToDecimal("8,7")
Dim sb As New System.Text.StringBuilder("""price"" is a ")
sb.Append(price.GetType.FullName)
sb.Append(" whose value is ")
If price < 1 Or price > 10 Then
sb.Append("NOT ")
End If
sb.Append("between 1 and 10.")
Debug.Print(sb.ToString)
ProductsTableAdapter.Insert("myProduct", price)
when I run it with Windows set to "English (United States)" I see the debug output
"price" is a System.Decimal whose value is NOT between 1 and 10.
and the value 87 is inserted into the database because the string "8,7" is not a valid decimal in that locale.
With Windows set to "Spanish (Spain)" the same code now produces
"price" is a System.Decimal whose value is between 1 and 10.
but the value 87 is still inserted.
With Windows set to "French (Canada)" the debug output is the same
"price" is a System.Decimal whose value is between 1 and 10.
however, the insert fails with "Data type mismatch in criteria expression."
The exact same results were achieved by replacing
ProductsTableAdapter.Insert("myProduct", price)
with
Dim myConnStr As String
myConnStr =
"Provider=Microsoft.ACE.OLEDB.12.0;" &
"Data Source=C:UsersPublicDatabase1.accdb"
Using con As New OleDbConnection(myConnStr)
con.Open()
Using cmd As New OleDbCommand("INSERT INTO Products ([name], price) VALUES (?,?)", con)
cmd.Parameters.AddWithValue("?", "oledbTest")
cmd.Parameters.AddWithValue("?", price)
cmd.ExecuteNonQuery()
End Using
End Using
proving that this is a problem between System.Data.OleDb
and the Access OLEDB provider, and not merely an idiosyncrasy of the TableAdapter. However, TableAdapters seem to rely exclusively on OleDb, so unfortunately they probably will just not work under these conditions.
The good news is that simply converting the OleDb code to Odbc appears to have fixed the issue for both the "Spanish (Spain)" and "French (Canada)" Windows locales
Dim myConnStr As String
myConnStr =
"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" &
"DBQ=C:UsersPublicDatabase1.accdb"
Using con As New OdbcConnection(myConnStr)
con.Open()
Using cmd As New OdbcCommand("INSERT INTO Products ([name], price) VALUES (?,?)", con)
cmd.Parameters.AddWithValue("?", "odbcTest")
cmd.Parameters.AddWithValue("?", price)
cmd.ExecuteNonQuery()
End Using
End Using
so one possible workaround might be to use an OdbcDataAdapter instead of a TableAdapter.