我需要修改一个旧的vb6应用程序,该应用程序需要从dBase IV数据库中导入一些数据。 过去,选择查询只涉及一个表(dbf文件),并且曾经可以完美地工作。
现在,我需要编辑此查询以使用多个字段在第二个表上引入联接。
这是我的代码的简化版本:
Dim cnn As New Connection
Dim rs As New Recordset
Dim sql As String
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Extended properties=dBase IV;Data source=d:\100\db;"
sql = "..." 'see below!
rs.CursorLocation = adUseClient
rs.Open sql, cnn, adOpenDynamic, adLockOptimistic
debug.print rs.RecordCount
rs.Close
cnn.Close
这两个表具有典型的主从结构;我检查了数据库文档并检查了TABFAT01和TABFAT02,因此可以假定:
[TABFAT01] 1 <-> n [TABFAT02]
,并在
TIPDOC (text)
,ANNDOC (text)
和NUMDOC (numeric)
字段。第一期
我的第一个查询是:
select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join
TABFAT02 c on t.TIPDOC = c.TIPDOC and t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC
此查询返回0条记录。
如果我更改条件,请按以下方式订购:
select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join
TABFAT02 c on t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC and t.TIPDOC = c.TIPDOC
查询返回907条记录。
我不了解条件顺序如何以及为什么会对查询结果产生影响。
第二个问题
如果我添加where子句:
select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT01 t inner join
TABFAT02 c on t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC and t.TIPDOC = c.TIPDOC
where c.LIBER04 = 'a'
查询返回0条记录。
但是,如果我运行此查询:
select * from TABFAT02 c where LIBER04 = 'a'
它返回1条记录,其中TIPDOC ='F2',ANNDOC ='2018',NUMDOC = 1854。
后续查询:
select * from TABFAT01 t where t.TIPDOC = 'F2' and t.ANNDOC = '2018' and t.NUMDOC = 1854
按预期返回1条记录。
除了TIPDOC之外,我尝试将所有带有联接表的where子句放在字段中时都会发生这种情况。 如果我按TIPDOC筛选,结果是正确的。
第三期
我第一次打开vb6 IDE后运行代码 时,出现以下错误:
Run-time error '-2147467259 (80004005)': Selected Collating sequence Not Supported by the operating system.
(我实际上使用的是意大利语版本的vb6,原始错误消息为“ Sequenza di ordinamento selezionata non supportata dal sistema operationtivo。”。 我想我上面写的消息与英文版本是正确的匹配。)
此错误不会在以后的运行中显示,直到我关闭并重新打开vb6 。
答案 0 :(得分:0)
首先清除您的错误消息。 “操作系统不支持选定的整理顺序。”可能意味着您没有指定整理顺序,或者Jet.OLEDB驱动程序不支持您指定的任何整理顺序。
我从来没有让Jet.OLEDB驱动程序与我的应用程序一起使用。我的猜测是因为我正在处理的文件是由FoxPro创建的。因此,我使用了Visual Fox Pro ODBC驱动程序。这是一个示例连接。 “ DSN = BCLVariance; UID =; SourceDB = C:\ AMSI \ BCLTemp; SourceType = DBF; Exclusive = Yes; BackgroundFetch = No; Collate = Machine; Null = Yes; Deleted = Yes;” 您将看到它允许您控制在Jet.OLEDB连接字符串中不受控制的各种参数。 ODBC数据源是在ODBC数据源管理器中的“系统数据源”选项卡下设置的。
我从不确切知道为什么,但是在SQL查询中陈述表名的顺序确实有所不同。它与内部查询解释器如何处理它们有关。您需要先指定明细表,然后将母版连接到该明细表。像这样:
select t.TIPDOC, t.NUMDOC, t.ANNDOC, t.DATDOC, t.LIBER03, c.LIBER04
from TABFAT02 c inner join
TABFAT01 t on t.TIPDOC = c.TIPDOC and t.ANNDOC = c.ANNDOC and t.NUMDOC = c.NUMDOC
这也可能会解决您的其他问题。试试看。
顺便说一句,您还需要将初始代码更改为:
if Not rs.BOF then
rs.MoveLast
debug.print "rs.RecordCount=";rs.RecordCount
else
debug.print "rs.BOF = True"
end if
答案 1 :(得分:0)
我同意thx1138v2的观点,即不专门使用Jet OleDB驱动程序,而是专门针对源代码。您提到了dBASE IV。这是准确的还是使用Visual FoxPro确实如此。您可以确认该表是否具有索引和注释(备注)字段,文件名后缀为
YourTable.dbf(实际表) YourTable.cdx(复合索引文件) YourTable.fpt(注释/备忘录文件的内容是表格中包含此类列的内容)。
已经确认,如果它是Visual Foxpro,我将直接从Microsoft获取Microsoft驱动程序。
如果正在从VFP外部的源更新数据表,则索引可能不同步,因为其他驱动程序不一定会正确打开索引文件(cdx)来保留新记录。同步因此,当尝试基于一系列连接子句进行连接时,它确实使用了非同步索引。但是更改顺序会强制默认为自然顺序,从而看到所有可能的记录都需要解决。
看到并希望这是有道理的,并有助于调整查询问题中缺少的链接。