aimingoo的第一次吐血提问!关于BDE!(200分)

  • 主题发起人 aimingoo
  • 开始时间
A

aimingoo

Unregistered / Unconfirmed
GUEST, unregistred user!
同志们呀!我实在无可忍受了,才发了这条消息求助!
================================================
在我主页的ISAPI程序中用了一段程序来打开数据库,并用SQL查询一些东
东!(请不要管什么ISAPI了,注意BDE部分就成)
但是,当我初始化这个.DLL,第一次使用程序时完全正常,也就是.DLL打
开第一个线程时没有问题。但在其后的访问中,只要调用.DLL的动作中存
在一个TQuery组件,并申请SQL查询。就出现如下错误:
Internal Server Error 500
----------------------------------------------------------
Exception: EDBEngineError
Message: Invalid handle to the function.

目前的分析结果:
================
1.同一个.dll,在同一个服务器,如果调用不使用数据库功能的动作,则
一切正常,证明.dll(我的ISAPI DLL程序)没有错误。
2.同一个.dll,在另一台服务器上,一切正常,请参见测试站点
http://202.102.224.3/aiming/。它们用的是同一个程序。服务器软件配
置也是一样的。BDE版本也是一样的。
3.程序出错的可能性很小。而且每次TQuery的SQL申请前,TQuery组件是
被我用theTable := TQuery.Create(nil)方法重建的,使用后即Free掉。
应该不存在在不同的DLL线程间使用了同一个TQuery句柄的问题!
4.可能性较大的是我的程序还需要一个.dll,而且这个.dll还与BDE有关,
同时,可能与共享内存和进程数据共享有关。——我思考过DelphiMM.dll,
但好象不是。 :(

目前的情况大致如此。请共研!如果有任何疑问或需要部分源码,请提出

不过全部源码超过千行,而且同时涉及ShareMem,ISAPI CGI, DLL和DataBase,
不大可能全部贴出,一段段地来吧…… :)))))))

====================
200大元呀!!!
 
TQuery.Create(nil)时需要TSession.Create(nil), TDataBase.Create(nil)
不然后继query没默认session和database可用
 
喔?
我可根本没有用TSession和TDataBase呀!在线么?可以用ICQ或者mIRC讨论就
好了,分我回头加给你。 :)
 
my ICQ:16902318
use mIRC: www.see.online.sh.cn:6667, #delphi, 我常在。 :)
 
怎么变成私下交易了
 
谁说成私下交易了?欢迎大家疯狂讨论!
(不过这样的问题可能很难疯狂起来,aim想……)

只是昨晚急了些,跟eYes到mIRC中聊了聊,没有准确结果。我正在测试
他说到的方法。
 
eYes的意思是一个线程用一个Tsession, 互不干扰, 你可以看一下
delphi 中的Back Query的例子, 我记得它是将每个query都定了一个
Tsession的.
 
不可能吧?!!
39个人浏览,就不能给点儿好想法?!(说这话之前,先感谢eYes和SesSky,并
希望和HuiZhang躲到一个被窝里去私下讨论一下下.嘿嘿,嘿嘿嘿嘿……)
 
把数据库搬到另一个目录试试,可能与http server的存取权限有冲突。
 
与http server目录权限无关。我用了一个.exe的程序测试相应
目录的读/写权限,完全正常。.exe中用的是和.dll中完全相同
的过程。
谢谢chenke.
 
CGI和ISPAI是有点区别的呀!试一下。
 
可能是server的权限!
 
可能是server的权限!
 
可能是server的权限!
 
2.同一个.dll,在另一台服务器上,一切正常,请参见测试站点
那么问题一定不在程序!
如果是少DLL, RE - INSTALL BDE AND SQL LINK
生计你的IIS服务器,
你用什么表,需要的话装INTERBASE

BDE这东西在DESKTOP上是不错的,上网...
 
呵呵,测试了Another_eYes的方法,搞定。

但是还是有些想不明白的地方,再请教:
1. 为什么我不用TSession,在另一个服务器上又没有问题呢?而且我
肯定能做到在同时访问数据库的(我用两个浏览器,不断刷新,撞鬼也
能撞到两个 :))。要知道,.dll肯定是一样的。服务器配置和BDE版本
也一致……

2. 我目前使用如下程序段来初始化和关闭数据库,由于我对DataBase
不通,所以提出来,请各位同参考,还有什么地方要注意的:
//source
===========
var txtTable: TQuery;
txtDatabase : TDataBase;
txtSession : TSession;

Function InitDatabase : boolean;
begin
txtSession := TSession.Create(nil);
txtDatabase := TDataBase.Create(nil);
txtTable := TQuery.Create(nil);
txtSession.SessionName := 'txtDBSession';
txtDatabase.SessionName := 'txtDBSession';
txtTable.SessionName := 'txtDBSession';
result := true;
end;

Function TerminateDatabase : boolean;
begin
txtTable.free;
txtDatabase.free;
txtSession.free;
result := true;
end;
===========
//调用部分
===========
begin
//...
InitDatabase;
with txtTable do
try
//do somethings...
finally
TerminateDatabase;
end;
end;
 
TSession的建立,:
第一步是声明一个TSession类型的变量。
第二步是调用TSession的Create创建一个TSession的对象实例。
Create会自动把Databases数组清为空,把KeepConnections属
性设为True,同时还把新创建的BDE会话期对象加到由Sessions
管理的BDE会话期对象的列表中。
第三步是设置SessionName属性指定此BDE会话期对象的名称,注
意不能与其他BDE会话期名称相同。TDatabase和数据集构件都是
通过名称来区分BDE会话期对象。
第四步是激活此BDE会话期对象,然后设置有关属性。
你的给session的SessionName需要有一个唯一的名称, 这样才不会
有冲突的可能性, 即在每个线程中的sessionname不能相同, 你
参看delphi中的一个例子Bkquery便可以知道如何确定一个唯一的
sessionname,

以下是线程查询的过程
procedure TQueryThread.Execute;
var
UniqueNumber: Integer;
begin
try
with QueryForm do
begin
{ Ensure the Query has a unique session and database. A unique session
is required for each thread. Since databases are session specific
it must be unique as well }
UniqueNumber := GetUniqueNumber; //这里的取得一个唯一数, 方法见例子
Session.SessionName := Format('%s%x', [Session.Name, UniqueNumber]);
Database.SessionName := Session.SessionName;

Database.DatabaseName := Format('%s%x', [Database.Name, UniqueNumber]);
Query.SessionName := Database.SessionName;
Query.DatabaseName := Database.DatabaseName;

{ Open the query }
Query.Open;

{ Connect the query to the grid. This must be done in a synchronzied
method since assigning the query to the DataSource will modify the
contents of the grid and the grid can only be modified from the main
VCL thread }
Synchronize(ConnectQuery);

{ Update the status line. Since the label is a VCL control this must
also be done in the main VCL thread }
MessageText := 'Query openned';
Synchronize(DisplayMessage);
end;
except
on E: Exception do
begin
{ Display any error we receive on the status line }
MessageText := Format('%s: %s.', [E.ClassName, E.Message]);
Synchronize(DisplayMessage);
end;
end;
end;
 
aimingoo, 问题解决了吗? 等着你分赃呢.
 
分分!!马上就分!!
快快去我的站看看吧,一切已经搞定了。
http://member.zz.ha.cn/~aiming/
----------------------------------------
分赃原则: ^-^
1. 当然不能是见者有份的啦;
2. Another_eYes给120分,是因为他的问题提到了点子上,的确
用TSession解决问题.涉及问题根本,所以120分.
3. SeaSky提供的程序完善了解决方案.因为我原来的程序段会
导致同时访问出错(TSession名不唯一).值80大元.
 
分分!!马上就分!!
快快去我的站看看吧,一切已经搞定了。
http://member.zz.ha.cn/~aiming/
----------------------------------------
分赃原则: ^-^
1. 当然不能是见者有份的啦;
2. Another_eYes给120分,是因为他的问题提到了点子上,的确
用TSession解决问题.涉及问题根本,所以120分.
3. SeaSky提供的程序完善了解决方案.因为我原来的程序段会
导致同时访问出错(TSession名不唯一).值80大元.
 
顶部