C++ Builder 6 和 Windows 7 64 位上的 ADOQuery
ADOQuery on C++ Builder 6 and Windows 7 64bit
我在使用 TADOQuery
组件时遇到了一个奇怪的问题。
我目前在一个地方工作,他们在 Windows XP VM 上使用 运行 的 Borland C++Builder 应用程序。所以我们想移动到 Windows 7 并将其用作终端,这样员工就可以接收带有 Windows 10 的新机器,而无需在每台机器上再次创建 Win XP VM。
目前该应用程序使用 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 不会将每次出现的 "BEN" 都替换为 0,我最终得到的结果集为 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。
这给我带来了结果,但不是马上。
它是这样工作的:应用程序是一个基于树的用户界面。有一个节点显示 "Today's Checks",展开后显示今天的支票。太棒了,现在这在 BDE 上非常有效,我只分配一次参数值,它会自动替换它看到的任何地方 "BEN",等等
使用 ADO 组件时,我展开 "Today's Checks" 节点和代码 运行s,加载参数,激活查询组件,但没有得到任何结果!所以节点保持折叠状态。如果我再次单击 +
符号展开树,它会加载支票!之后每次都会加载它们。
因此,在应用程序中有一个日期选项,默认为今天的日期。如果我将其更改为昨天的日期,我仍然会收到今天的支票……就像参数没有得到更新一样。如果我一开始就尝试从不同的日期开始,我不会得到任何结果!它会带来今天日期的结果,但之后它不会接受不同的日期。
我调试了代码,日期发生了变化,但出于某种原因,参数没有发生变化。这是我的代码块:
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 的用户界面,但仍在构建中。在那之前,我需要将所需的 changes/updates 作为我工作的一部分。
好的,我已经开始工作了!!
对于在 Windows 7 64 位上使用 BDE 苦苦挣扎的任何人,这里有一个解决方案!请记住,我正在处理的数据库是使用 C++ Builder 6 构建的 Oracle 8i 和 Borland C++ 应用程序。
按照照片和箭头。我试着给每张照片加上自己的评论,但后来这个网站说我不能 post 超过 2 个链接...让他们见鬼去吧,所以我把所有的都放在一张照片上。
例如,此 TQuery 正在寻找 bnetdata 作为数据库。太好了,在下一张图中我们添加一个 ADOConnection 组件
单击突出显示的连接字符串。
选择使用连接字符串并点击构建。
Select 突出显示的提供商,然后单击下一步。
勾选使用数据源名称然后点击箭头指向select一个。注意稍后输入用户名和密码,勾选允许保存密码。
Select BDE 组件正在使用的相同数据源。请注意,这是 ODBC 管理器中系统 DSN 下的来源之一。如果不存在,则创建一个。
这是 ODBC 管理员的截图。注意这里还是XP环境。您将需要在 windows 7 机器上创建相同的数据源(在我的例子中是 bnetdata)。
现在点击高级并检查列表中的读写选项。
在您单击 ADOConnection 组件上的“确定”之后,正如您现在在对象检查器中看到的那样。查看突出显示的区域。现在,我们需要将 connected 属性 设置为 true。当您这样做时,它会要求您登录数据库。输入用户名和密码,然后单击“确定”。连接 属性 现在将变为真。之后,您需要将 LoginPrompt 属性 设置为 false。现在单击项目上的保存。
假设您也有 BDE 数据库组件,单击它然后清除别名和驱动程序名称,然后将您的数据库名称放在 databaseName 属性 下(在我的例子中是 bnetdata)。
保存项目并在XP中编译。把应用程序复制粘贴到Windows7机器上双击就可以了!我已经成功地将所有应用程序转换为在 Windows 7 上工作。最困难的部分是安装 Borland 并让 Windows 7 在 ODBC 管理器的驱动程序选项卡下识别 Oracle ODBC 驱动程序。
同样,SQL Borland 安装附带的资源管理器将无法工作。因此,我仍然需要在我的 Windows XP VM 中进行开发,但用户可以在 Windows 7 VM 中使用该应用程序作为 Windows 服务器上的终端...对我有用! !
希望这对某人有所帮助!
编辑:
我还在 ADOConnection 中尝试了 Microsoft OLE DB Provider for Oracle,它也有效。没有看到对速度或性能的可衡量影响。两者似乎以相同的方式执行。我很惊讶如何添加 ADOConnection 组件允许应用程序连接到数据库并像在 XP 中一样工作!
另外,为了清楚起见,您不需要更改应用程序中的 BDE 组件。只需要添加 ADOConnection,所有其他组件保持不变(BDE 组件)。我试图转换为使用 ADO 组件,但不再需要了。
我在使用 TADOQuery
组件时遇到了一个奇怪的问题。
我目前在一个地方工作,他们在 Windows XP VM 上使用 运行 的 Borland C++Builder 应用程序。所以我们想移动到 Windows 7 并将其用作终端,这样员工就可以接收带有 Windows 10 的新机器,而无需在每台机器上再次创建 Win XP VM。
目前该应用程序使用 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 不会将每次出现的 "BEN" 都替换为 0,我最终得到的结果集为 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。
这给我带来了结果,但不是马上。
它是这样工作的:应用程序是一个基于树的用户界面。有一个节点显示 "Today's Checks",展开后显示今天的支票。太棒了,现在这在 BDE 上非常有效,我只分配一次参数值,它会自动替换它看到的任何地方 "BEN",等等
使用 ADO 组件时,我展开 "Today's Checks" 节点和代码 运行s,加载参数,激活查询组件,但没有得到任何结果!所以节点保持折叠状态。如果我再次单击 +
符号展开树,它会加载支票!之后每次都会加载它们。
因此,在应用程序中有一个日期选项,默认为今天的日期。如果我将其更改为昨天的日期,我仍然会收到今天的支票……就像参数没有得到更新一样。如果我一开始就尝试从不同的日期开始,我不会得到任何结果!它会带来今天日期的结果,但之后它不会接受不同的日期。
我调试了代码,日期发生了变化,但出于某种原因,参数没有发生变化。这是我的代码块:
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 的用户界面,但仍在构建中。在那之前,我需要将所需的 changes/updates 作为我工作的一部分。
好的,我已经开始工作了!!
对于在 Windows 7 64 位上使用 BDE 苦苦挣扎的任何人,这里有一个解决方案!请记住,我正在处理的数据库是使用 C++ Builder 6 构建的 Oracle 8i 和 Borland C++ 应用程序。
按照照片和箭头。我试着给每张照片加上自己的评论,但后来这个网站说我不能 post 超过 2 个链接...让他们见鬼去吧,所以我把所有的都放在一张照片上。
例如,此 TQuery 正在寻找 bnetdata 作为数据库。太好了,在下一张图中我们添加一个 ADOConnection 组件
单击突出显示的连接字符串。
选择使用连接字符串并点击构建。
Select 突出显示的提供商,然后单击下一步。
勾选使用数据源名称然后点击箭头指向select一个。注意稍后输入用户名和密码,勾选允许保存密码。
Select BDE 组件正在使用的相同数据源。请注意,这是 ODBC 管理器中系统 DSN 下的来源之一。如果不存在,则创建一个。
这是 ODBC 管理员的截图。注意这里还是XP环境。您将需要在 windows 7 机器上创建相同的数据源(在我的例子中是 bnetdata)。
现在点击高级并检查列表中的读写选项。
在您单击 ADOConnection 组件上的“确定”之后,正如您现在在对象检查器中看到的那样。查看突出显示的区域。现在,我们需要将 connected 属性 设置为 true。当您这样做时,它会要求您登录数据库。输入用户名和密码,然后单击“确定”。连接 属性 现在将变为真。之后,您需要将 LoginPrompt 属性 设置为 false。现在单击项目上的保存。
假设您也有 BDE 数据库组件,单击它然后清除别名和驱动程序名称,然后将您的数据库名称放在 databaseName 属性 下(在我的例子中是 bnetdata)。
保存项目并在XP中编译。把应用程序复制粘贴到Windows7机器上双击就可以了!我已经成功地将所有应用程序转换为在 Windows 7 上工作。最困难的部分是安装 Borland 并让 Windows 7 在 ODBC 管理器的驱动程序选项卡下识别 Oracle ODBC 驱动程序。
同样,SQL Borland 安装附带的资源管理器将无法工作。因此,我仍然需要在我的 Windows XP VM 中进行开发,但用户可以在 Windows 7 VM 中使用该应用程序作为 Windows 服务器上的终端...对我有用! !
希望这对某人有所帮助!
编辑:
我还在 ADOConnection 中尝试了 Microsoft OLE DB Provider for Oracle,它也有效。没有看到对速度或性能的可衡量影响。两者似乎以相同的方式执行。我很惊讶如何添加 ADOConnection 组件允许应用程序连接到数据库并像在 XP 中一样工作!
另外,为了清楚起见,您不需要更改应用程序中的 BDE 组件。只需要添加 ADOConnection,所有其他组件保持不变(BDE 组件)。我试图转换为使用 ADO 组件,但不再需要了。