2016-03-09 50 views
1

我在使用TADOQuery组件时出现了一个奇怪的问题。在C++ Builder 6和Windows 7 64位上的ADOQuery

我目前的工作地点是使用在Windows XP虚拟机上运行的Borland C++ Builder应用程序。因此,我们希望转移到Windows 7并将其作为终端提供服务,这样员工就可以使用Windows 10接收新计算机,而无需在每台计算机上再次创建Win XP虚拟机。

目前该应用程序使用BDE组件,它在XP上运行良好。我们创建了一个用于测试的Win7 64位虚拟机,并安装了必要的驱动程序等,但是BDE无法正常工作。当我尝试通过Borland附带的SQL Explorer进行登录时,它只是挂起。它发送请求但从未得到响应。我花了一个多星期的时间试图调试这个问题,但没有得到它的任何地方。

无论如何,我放弃了BDE,并想尝试改用ADO。所以我开始时只需创建一个TDBGrid并使用ADO组件填充数据。它在XP和Win7上都很棒!所以现在我试图将应用程序的BDE组件(TDataBase,TQuery等)转换为ADO组件。

尝试使用参数时遇到了一个有趣的问题。下面是一个查询示例:

SELECT t1.SEC_CODE, t1.CODE, t1.CTRL_NUM, t1.CHECK_CODE, 
t1.CHECK_NO, t1.CLIENT_ID, t1.AMOUNT, t1.TRANS_NO, decode(t2.prefix,null,t2.name,t2.name||', '||t2.prefix) as fullName, 
t1.ENTRY_DATE, t1.DEPOSIT_DATE, t1.ACCT_COMMENT, t2.NAME, t2.PREFIX 
FROM ACCOUNTING.ACCT_CHECK_IN t1, OISC.CLIENT t2 
WHERE 
(:BEN =1 OR (:BEN =0 AND t1.ENTRY_DATE=:DATE) 
OR (:BEN =2 AND t1.DEPOSIT_DATE IS NOT NULL) 
OR (:BEN =3 AND t1.DEPOSIT_DATE IS NULL)) AND 
(:ALEX =1 OR (:ALEX =0 AND t1.ENTRY_DATE>=:DATE1 AND 
t1.ENTRY_DATE<=:DATE2) OR (:ALEX =2 AND t1.DEPOSIT_DATE>=:DATE1 
AND t1.DEPOSIT_DATE<=:DATE2)) 
AND T2.CLIENT_ID(+)=T1.CLIENT_ID 

ORDER BY t1.SEC_CODE, t1.CHECK_CODE, fullName, t1.check_no 

请不要注意参数的名字,这对我来说有点滑稽,但你们将无法进行连接。

这里的第一个问题是,即使某些参数是相同的名称,ADO将它们视为单个参数!所以,如果我这样做:

checkload1->Parameters->ParamByName("BEN")->Value=0 

ADO不会取代0“BEN”的每一次出现,我结束了一个结果集的0记录!相反,我使用的是:

checkload1->Parameters->Items[0]->Value = 0; // BEN param 
checkload1->Parameters->Items[1]->Value = 0; 
checkload1->Parameters->Items[3]->Value = 0; 
checkload1->Parameters->Items[4]->Value = 0; 

基本上,将基于参数索引的每个“BEN”参数替换为0。

这给我带来了结果,但不是马上。

所以,它是如何工作的:应用程序是一个基于树的用户界面。有一个节点会显示“今天的支票”,并在展开时显示今天的支票。好极了,现在这个BDE的工作很棒,我只分配参数值一次,它会自动替换它看到的所有“BEN”等。

当使用ADO组件时,我展开“Today's Checks”节点和代码运行,加载参数,激活查询组件,我没有结果!所以节点保持折叠状态。如果我再次点击+标志展开树,它会加载检查!之后每次都会加载它们。

因此,在应用程序中有一个日期选项,默认为今天的日期。如果我将其更改为昨天的日期,我仍然得到今天的检查...这就像参数没有得到更新。如果我试着从一开始就用不同的日期开始,我没有得到任何结果!它会带来今天的结果,但在此之后它不会接受不同的日期。

我调试了代码和日期正在改变,但由于某些原因,参数没有改变。这里是我的代码块:

checkload1->Filter="" ; 
checkload1->Filtered=false ; 
switch(params) 
    { 
    case 0: checkload1->Parameters->Items[0]->Value = 1; // BEN param 
      checkload1->Parameters->Items[1]->Value = 1; 
      checkload1->Parameters->Items[3]->Value = 1; 
      checkload1->Parameters->Items[4]->Value = 1; 
      // ALEX Param 
      checkload1->Parameters->Items[5]->Value = 0; 
      checkload1->Parameters->Items[6]->Value = 0; 
      checkload1->Parameters->Items[9]->Value = 0; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS NOT IN ('Refunded', 'Posted') "; 
      break ; 
    case 1: checkload1->Parameters->Items[0]->Value = 0; // BEN param 
      checkload1->Parameters->Items[1]->Value = 0; 
      checkload1->Parameters->Items[3]->Value = 0; 
      checkload1->Parameters->Items[4]->Value = 0; 
      checkload1->Parameters->ParamByName("DATE")->Value=FormatDateTime("dd-mmm-yyyy", Date()) ; 
      checkload1->SQL->Strings[13] = " "; 
      break ; 
    case 2: checkload1->Parameters->Items[0]->Value = 2; // BEN param 
      checkload1->Parameters->Items[1]->Value = 2; 
      checkload1->Parameters->Items[3]->Value = 2; 
      checkload1->Parameters->Items[4]->Value = 2; 
      //ALEX param 
      checkload1->Parameters->Items[5]->Value = 2; 
      checkload1->Parameters->Items[6]->Value = 2; 
      checkload1->Parameters->Items[9]->Value = 2; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Deposited') "; 
      break ; 
    case 3: checkload1->Parameters->Items[0]->Value = 3; // BEN param 
      checkload1->Parameters->Items[1]->Value = 3; 
      checkload1->Parameters->Items[3]->Value = 3; 
      checkload1->Parameters->Items[4]->Value = 3; 
      //ALEX param 
      checkload1->Parameters->Items[5]->Value = 0; 
      checkload1->Parameters->Items[6]->Value = 0; 
      checkload1->Parameters->Items[9]->Value = 0; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Held') "; 
      break ; 
    } 
if(!mainform->date1->Checked){ 
checkload1->Parameters->Items[5]->Value = 1; 
checkload1->Parameters->Items[6]->Value = 1; 
checkload1->Parameters->Items[9]->Value = 1; 
} 
checkload1->Parameters->Items[7]->Value = FormatDateTime("dd-mmm-yyyy", fromdate); 
checkload1->Parameters->Items[10]->Value = FormatDateTime("dd-mmm-yyyy", fromdate); 
checkload1->Parameters->Items[8]->Value = FormatDateTime("dd-mmm-yyyy", todate); 
checkload1->Parameters->Items[11]->Value = FormatDateTime("dd-mmm-yyyy", todate); 

if(filters != "") checkload1->SQL->Strings[12] = filters; 
else checkload1->SQL->Strings[12]=" " ; 
checkload1->Prepared = true; 
checkload1->Active=true ; 

有人可以有经验告诉我这个吗?

我知道这是古老的东西,但这些程序的字面意思是15 - 20年前,他们正在转向基于Web的用户界面,但仍在构建中。在此之前,我需要将所需的更改/更新作为我工作的一部分。

回答

1

好吧,我得到了这个工作!

对于那些与BDE一起努力工作在Windows 7 64位上的人,这里有一个解决方案!请记住我正在处理的数据库是使用C++ Builder 6构建的Oracle 8i和Borland C++应用程序。

请按照照片和箭头。我试图把每张照片都带上自己的评论,但是这个网站说我不能发布2个以上的链接......与他们见面,所以我把所有的照片放在一张照片上。

Follow the arrows and hopefully you can connect it with my comments below.

这TQuery的例如正在寻找bnetdata作为数据库。太棒了,在下一张图片中,我们添加了一个ADOConnection组件

单击突出显示的连接字符串。

选择使用连接字符串,然后单击构建。

选择突出显示的提供程序,然后单击下一步。

检查使用数据源名称,然后单击箭头以选择一个。请注意,您稍后将输入用户名和密码并检查是否允许保存密码。

选择与BDE组件使用的数据源相同的数据源。请注意,这是ODBC管理器中您的系统DSN下的源之一。如果它不在那里,那就创建一个。

这是来自ODBC管理员的一个镜头。请注意,这仍然是XP环境。你将需要在Windows 7机器上创建相同的数据源(在我的情况下是bnetdata)。

现在点击高级并从列表中选择readwrite选项。

单击ADOConnection组件上的OK后,就像您现在在对象检查器中看到的一样。看看突出显示的区域。现在,我们需要将连接属性设置为true。当你这样做时,它会要求你登录到数据库。输入用户名和密码,然后单击确定。连接属性现在将成为真实的。之后,您需要将LoginPrompt属性设置为false。现在点击保存项目。假设你有BDE数据库组件,点击它,然后清除别名和驱动程序名称,然后把你的数据库名称放在databaseName属性下(在我的情况下它是bnetdata)。

保存项目并在XP中编译。复制应用程序并将其粘贴到Windows 7机器中,然后双击它,它就会起作用!我已成功转换所有应用程序以在Windows 7上运行。最难的部分是安装Borland并让Windows 7在ODBC管理器的“驱动程序”选项卡下识别Oracle ODBC驱动程序。

再一次,Borland安装附带的SQL Explorer不起作用。所以,我仍然需要在我的Windows XP虚拟机上开发,但用户可以使用Windows 7虚拟机中的应用程序作为Windows服务器上的终端...适用于我!

希望这可以帮助别人!

编辑:

我也试过的Microsoft OLE DB提供程序的Oracle中的ADOConnection,它也工作了。没有看到对速度或性能产生可衡量的影响。两者似乎都以相同的方式执行。我很惊讶如何添加ADOConnection组件允许应用程序连接到数据库并像在XP中一样工作!

也只是为了清除问题,您不需要更改应用程序中的BDE组件。只需要添加ADOConnection和所有其他组件即可(BDE组件)。我试图转换为使用ADO组件,但没有必要了。

Microsoft OLE DB Provider for Oracle