VB.NET - Visual Foxpro OLE DB 数字小数列问题
简而言之: 我正在使用 VB.NET 2008 通过 vfpoledb.1 驱动程序连接到 Visual Foxpro 6 数据库。当我尝试使用包含数字列之一的数据集表填充 OleDbDataAdapter 时,收到以下错误消息:
提供程序无法确定十进制值。例如,刚刚创建该行,Decimal 列的默认值不是 可用,并且消费者尚未设置新的 Decimal 值。
我想从 VB.NET 2008 检索此列并将其保留为数字格式。
长版本:
我正在使用 VB.NET 连接到 Visual Foxpro 6 数据库。表中的几列适用于最多 8 位数字的数字数据类型。我不确定 Visual Foxpro 数据类型如何工作,但似乎该字段允许某人输入以下任何示例值:
99999999
99999.99
9.99
9.00
{nothing}
来自 Visual Foxpro:我可以访问名为 Foxwin 的小程序,它允许我浏览原生VFP环境。这就是我用来访问数据以获取我上面发布的示例的方法。从这里我可以看到,有些行在该字段中根本不包含任何值,尽管在没有数据时它们似乎填充了空格。我尝试运行更新查询来用有效数据填充每一行,但我的更新查询完成时没有更新任何行。我尝试过 ISNULL(bal_qty) 和 bal_qty IS NULL 但都不起作用。
从 MS Access 2007 开始:使用与 VB.NET 中使用的驱动程序相同的驱动程序,我可以毫无问题地加载 ADO 记录集并将其绑定到表单。小数值似乎被去掉了,可能是因为它们都是“.00”。我更喜欢在 VB.NET 中构建这个小程序,因此我仅使用 MS Access 进行测试。
来自 VB.NET:如果我将 bal_qty 转换为 String,我的 SQL 语句可以工作,但这会导致排序问题。我尝试过 VAL(STR(bal_qty)) 但失败并显示与我上面发布的相同的错误消息。这是我正在使用的代码:
Imports System.Data.OleDb
Public Class Form1
Dim sConString As String = "Provider=vfpoledb.1;Data Source=C:\MyDatabase.dbc;Mode=3;"
Dim con As OleDbConnection = New OleDbConnection(sConString)
Private Function FetchData()
con.Open()
Dim ds As DataSet = New DataSet()
Dim sSQL As String
'This SQL statement works but the data doesn't sort properly.
'sSQL = "SELECT item_cd, item_desc, STR(bal_qty) FROM invent;"
sSQL = "SELECT item_cd, item_desc, bal_qty FROM invent;"
Dim cmd As OleDbCommand = New OleDbCommand(sSQL, con)
Dim daInv As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim iRecCount As Integer
iRecCount = daInv.Fill(ds, "invent") 'The error occurs here.
Me.DataGridView1.DataSource = ds.Tables("invent").DefaultView
End Function
Private Sub btnFetchData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetchData.Click
Call FetchData()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
con.Close()
con = Nothing
End Sub
End Class
In Short:
I'm using VB.NET 2008 to connect to a Visual Foxpro 6 Database using the vfpoledb.1 driver. When I attempt to fill an OleDbDataAdapter with a dataset table that contains one of the numeric columns, I get the following error message:
The provider could not determine the Decimal value. For example, the row was just created, the default for the Decimal column was not
available, and the consumer had not yet set a new Decimal value.
I'd like to retrieve this column from VB.NET 2008 and keep it in a numeric format.
The Long Version:
I'm using VB.NET to connect to a Visual Foxpro 6 database. Several of the columns in the table are intended for numeric data type of up to 8 digits. I'm not sure how Visual Foxpro data types work but it appears that this field allows someone to enter any of the following example values:
99999999
99999.99
9.99
9.00
{nothing}
From Visual Foxpro: I have access to small program called Foxwin that allows me to browse the VFP tables in a native VFP environment. This is what I'm using to access the data to obtain my examples for what I posted above. From here I can see that some rows contain no values at all in this field although they appear to be filled with spaces when there is no data. I've tried to run update queries to fill in every row with valid data but my update queries finish without updating any rows. I've tried ISNULL(bal_qty) and bal_qty IS NULL and neither one works.
From MS Access 2007: Using the same driver that I'm using in VB.NET and I can load the ADO recordset and bind it to a form without a problem. The decimal values appear to be stripped off, probably because all of them are ".00". I prefer to build this small program in VB.NET so I'm using MS Access only for testing.
From VB.NET: My SQL statement works if I convert bal_qty to String but this causes sort problems. I've tried VAL(STR(bal_qty)) and it fails with the same error message I've posted above. Here's the code I'm using:
Imports System.Data.OleDb
Public Class Form1
Dim sConString As String = "Provider=vfpoledb.1;Data Source=C:\MyDatabase.dbc;Mode=3;"
Dim con As OleDbConnection = New OleDbConnection(sConString)
Private Function FetchData()
con.Open()
Dim ds As DataSet = New DataSet()
Dim sSQL As String
'This SQL statement works but the data doesn't sort properly.
'sSQL = "SELECT item_cd, item_desc, STR(bal_qty) FROM invent;"
sSQL = "SELECT item_cd, item_desc, bal_qty FROM invent;"
Dim cmd As OleDbCommand = New OleDbCommand(sSQL, con)
Dim daInv As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim iRecCount As Integer
iRecCount = daInv.Fill(ds, "invent") 'The error occurs here.
Me.DataGridView1.DataSource = ds.Tables("invent").DefaultView
End Function
Private Sub btnFetchData_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnFetchData.Click
Call FetchData()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
con.Close()
con = Nothing
End Sub
End Class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我们在读取 FoxPro dbf 的 .NET 应用程序时遇到了这个问题。我们的解决方案是在 select 语句中使用以下内容:
这会将小数列 (SaleAmt) 转换为字符串,然后再转换回数值。此外,如果需要整数,您可以在 SELECT 语句中使用 INT(SaleAmt)。
We have this problem with a .NET app that reads foxpro dbf's. Our solution was to use the following in the select statement:
This converts the decimal column (SaleAmt) to a string and then back to a numeric value. Additionally, if an integer is desired, you can use INT(SaleAmt) in your SELECT statement.
我已经找到了导致此问题的问题。在 bal_qty 列/字段中输入的数字数据不符合列的数据类型定义。
我的字段 bal_qty 的 Visual Foxpro 数据定义为:
类型:数字
宽度:8
十进制:2
Visual Foxpro 软件显然允许用户在此字段中输入值 1000987,据我所知,这不会在 Visual Foxpro 中引起问题。但是,当使用 Visual Foxpro 以外的任何工具访问数据时,它确实会导致问题,因为它违反了该字段的设置。
进一步测试发现MS Access 2007也存在这个值的问题。将记录集加载到我的数据表视图表单后,我收到错误:“数据提供程序或其他服务返回了 E_FAIL 状态。”如果我包含以下 WHERE 子句,则不会收到错误: WHERE bal_qty < 9999
我现在已经通过运行 SQL UPDATE 语句来更改有问题记录中的 bal_qty 值来解决该问题。
我还在名为“标记”的列中发现了错误数据。数百条记录在应显示数字数据的地方仅显示星号。在我的记录集查询中包含此标记列也会导致我的查询失败并出现错误。
请参阅此 SO 帖子,了解数字列中的星号以及如何从 .NET 处理它:
如何读取星号 (***) 字段.DBF 数据库?
如果您尝试解决此问题,您可以使用 Visual RunFox 6 本机查看和编辑 VFP 数据,该软件在 Ed Leafe 的网站上是免费的:http://leaf.com/dls/vfp 您还可以从此处编辑表结构。除非您是经验丰富的 VFP 程序员,否则该工具远非直观。您必须从命令窗口输入 VFP 命令才能完成您想要执行的大部分操作。
I've found the problem that was causing this. In the bal_qty column/field there was numeric data entered that didn't conform to the column's data type definition.
My field bal_qty has a Visual Foxpro data definition of:
Type: Numeric
Width: 8
Decimal: 2
The Visual Foxpro software apparently allowed the user to enter a value of 1000987 in this field which, as near as I can tell, doesn't cause an issue in Visual Foxpro. However, it does cause problems when accessing the data using anything other than Visual Foxpro because it violates the settings for this field.
Further testing revealed that MS Access 2007 also has a problem with this value. After loading the recordset into my Datasheet view form I get the error: "Data provider or other service returned an E_FAIL status." If I include the following WHERE clause I do not get the error: WHERE bal_qty < 9999
I've now resolved the problem by running an SQL UPDATE statement to change the value of bal_qty in the offending record.
I also found bad data in a column called markup. Hundreds of records are showing only asterisks where they should be showing numeric data. Including this markup column in my recordset queries causes my queries to fail with errors also.
See this SO Post concerning Asterisks in Numeric Columns and how to deal with it from .NET:
How do I read asterisk (***) fields from .DBF data base?
If you're trying to resolve this problem you can view and edit VFP data natively using Visual RunFox 6 which is free on Ed Leafe's website: http://leafe.com/dls/vfp You can also edit the table structure from here. This tool is far from intuitive unless you are an experienced VFP programmer. You have to enter VFP commands from the command window for most everything you want to do.
我通过 C# 和 VB 使用 VFP 处理许多带/不带小数的表,没有出现任何问题。至于数据的排序,您可以将“order by”子句添加到选择中,以便其默认以预排序模式从 VFP 向下进入 VB。
此外,在我构建的版本中,我不会查询数据集,并且不知道这是否可能在某个地方出现问题...
至于数字内容,来自您的 DBF 查看器实用程序,输入掩码表结构的默认值应为其预期值...浏览到任何记录,进入字段并开始输入“9.99999”,即“9”。将强制您输入已知的小数位置,然后继续在小数点后输入 9,看看有多少实际可用位置。我可以想象,如果您尝试输入一个比其允许的小数精度更高的值,它可能会困扰您。
I've worked with VFP through C# and VB with many tables with/without decimals without problems. As for the ordering of data, you could add the "order by" clause to the select so its default coming DOWN from VFP into VB in a presorted mode.
Additionally, in the version's I've built, I don't query into a dataset, and don't know if that might be a problem somewhere somehow...
As for the numeric content, from your DBF Viewer utility, the input mask of the table structure should default to its expecting values... browse to any record, get into th field and start typing "9.99999", so "9." will force you to ITs known decimal location, then keep typing 9's after the decimal see how many actual places ARE available. I could see how it might nag you if you try to put in a value with greater decimal precision than it allows.