通过传递数据库句柄(TDatabase::Handle)给dll,以及在dll中多线程访问的问题?

ZouMorn 2003-09-12 10:57:15
加精
一个主窗口,连接数据库。有一个TSession对象MSession,以及所属的TDatabase对象MDatabase。想通过参数传递将数据库的句柄 MDatabase->Handle 传递给dll,以实现数据库连接的共享,并且每个dll中的访问是线程独立的,也就是说与主窗口不在一个线程中。遇到如下问题:

1、dll中数据库句柄的使用,动态创建一个数据库对象,然后将句柄赋值。而创建的记录集(TTable, TQuery)找不到动态创建的数据库名称。不过我创建了一个窗口,然后添加将数据库组件。dll初始化的时侯就创建窗口,将数据库句柄赋值后打开(TDatabase::Open()),可以正常通过数据库名(TDatabase::DatabaseName)访问。是否有更好的办法?

2、多线程对数据库经行查询的时侯(不同的线程不会访问同一个表,也就是说每个线程有单独的表数据,只是要共享连接而已),有不确定的时侯查询不出数据,时而对时而错。但是在查询(TQuery::Open())和判断(TQuery::RecordCount == 0)之间对数据库进行任何操作(如调用主窗口函数插入数据,或者加两句:MQuery->Database->StartTransaction(); MQuery->Database->Commit();)以后正常(得到正常的记录数)。请问如何解决?

多写高手不吝赐教!
...全文
117 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZouMorn 2003-09-19
  • 打赏
  • 举报
回复
我用该相同的方法,但是说是找不到数据库名。
不过,还是谢谢各位了。
kingcaiyao 2003-09-18
  • 打赏
  • 举报
回复
为什么不用数据模块呢?用数据模块不就可以实现连接共享?
sczyq 2003-09-18
  • 打赏
  • 举报
回复
的确. __property TDatabase Database = {read=FDatabase}; Database属性是不可写的.

你可以试试改成将
Query1->DatabaseName = Database->DatabaseName;

如果还不行,还可试试复制一个控件.

TDatabase *MyDatabase = new TDatabase(this);
MyDatabase->DatabaseName = "h11111111111"; // 不要重复.
MyDatabase->DriverName = Database->DriverName;
MyDatabase->Params = Database->Params;
MyDatabase->LoginPrompt = false;
Query1->DatabaseName = MyDatabase->DatabaseName;
....
delete MyDatabase;
ZouMorn 2003-09-18
  • 打赏
  • 举报
回复
哪位大哥帮帮忙!拜托。
sczyq 2003-09-18
  • 打赏
  • 举报
回复
经过测试,是可以的.

//--- 以下是EXE文件的调用: -----------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
if (Edit1->Text.ToIntDef(0) < 1) return;
if (!Database1->Connected)
Database1->Open();
if (Database1->Connected)
{
HINSTANCE Installed;
AnsiString (__stdcall *GetItemCaption)(TDatabase *, int) = NULL;
Installed = LoadLibrary("NormalDLL.dll");
if (Installed)
{
(FARPROC) GetItemCaption = GetProcAddress(Installed,"TestDb");
if (GetItemCaption)
Edit2->Text = GetItemCaption(Database1, Edit1->Text.ToIntDef(0));
}
FreeLibrary(Installed);
}
}

//--- 以下是DLL文件的函数: -----------------------------

extern "C" __declspec(dllexport)
AnsiString __stdcall TestDb(TDatabase *Database, int Id);
AnsiString __stdcall TestDb(TDatabase *Database, int Id)
{
AnsiString Result;
TQuery *Query = new TQuery(NULL);
Query->DatabaseName = Database->DatabaseName;
Query->SQL->Add("SELECT Caption FROM Items Where Id=" + IntToStr(Id));
Query->Open();
if (!Query->Eof)
Result = Query->FieldByName("Caption")->AsString;
Query->Close();
delete Query;
return Result;
}

ZouMorn 2003-09-18
  • 打赏
  • 举报
回复
我的程序之所以要传递数据库的句柄,就是为了实现
动态创建数据库实例
将数据库的名字(DatabaseName)给记录集(TTable, TQuery)
然后,访问记录集。
直接传递进来的数据库对象的名字、或者指针都是不好用的。

并且我创建的数据库不需要再次连接,只是共享句柄,然后“广播”他的“数据库名字”罢了。

那么我用数据库模块,在我这种情况之下又该如何实现共享呢?

ZouMorn 2003-09-17
  • 打赏
  • 举报
回复
楼上的兄弟,这样好像不行吧。TQuery::DabaBase 属性是不可用的。而且我的BDE句柄留出来可以供 BCB 6.0 使用,要是不传句柄你让我传什么?
supwjhuLoveCjj 2003-09-17
  • 打赏
  • 举报
回复
关注一下
sczyq 2003-09-16
  • 打赏
  • 举报
回复
为什么要传递将数据库的句柄 MDatabase->Handle 呢?我实在想不通.

若没有实在意思,建议传递将数据库的指针,

如:DLL库的函数:
MyFunction(TDatabase *Database)
{
Query1->DataBase = Database;
......
}


调用时:

MyFunction(Database1);
ZouMorn 2003-09-16
  • 打赏
  • 举报
回复
期待
csdnxw 2003-09-15
  • 打赏
  • 举报
回复
唉!帮你up吧,我还没有用BC连接过数据库
kinglh 2003-09-15
  • 打赏
  • 举报
回复
我不知道 帮你顶一下
ZouMorn 2003-09-15
  • 打赏
  • 举报
回复
人呢?
ZouMorn 2003-09-12
  • 打赏
  • 举报
回复
还有:

我用的是 MS SQL Server,配置 ODBC
BCB 5.5 和 BCB 6.0 的句柄会不会冲突?

对写 ==> 多谢 !
ZouMorn 2003-09-12
  • 打赏
  • 举报
回复
还有,我用的是 SQL Server 配置的 ODBC, BCB 5.5 和 BCB 6.0 的句柄会不会冲突?

对写 ==> 多谢 !

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧