1、dll中数据库句柄的使用,动态创建一个数据库对象,然后将句柄赋值。而创建的记录集(TTable, TQuery)找不到动态创建的数据库名称。不过我创建了一个窗口,然后添加将数据库组件。dll初始化的时侯就创建窗口,将数据库句柄赋值后打开(TDatabase::Open()),可以正常通过数据库名(TDatabase::DatabaseName)访问。是否有更好的办法?
2、多线程对数据库经行查询的时侯(不同的线程不会访问同一个表,也就是说每个线程有单独的表数据,只是要共享连接而已),有不确定的时侯查询不出数据,时而对时而错。但是在查询(TQuery::Open())和判断(TQuery::RecordCount == 0)之间对数据库进行任何操作(如调用主窗口函数插入数据,或者加两句:MQuery->Database->StartTransaction(); MQuery->Database->Commit();)以后正常(得到正常的记录数)。请问如何解决?
多写高手不吝赐教!
15 个解决方案
#1
还有,我用的是 SQL Server 配置的 ODBC, BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
对写 ==> 多谢 !
#2
还有:
我用的是 MS SQL Server,配置 ODBC
BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
我用的是 MS SQL Server,配置 ODBC
BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
#3
人呢?
#4
我不知道 帮你顶一下
#5
唉!帮你up吧,我还没有用BC连接过数据库
#6
期待
#7
为什么要传递将数据库的句柄 MDatabase->Handle 呢?我实在想不通.
若没有实在意思,建议传递将数据库的指针,
如:DLL库的函数:
MyFunction(TDatabase *Database)
{
Query1->DataBase = Database;
......
}
调用时:
MyFunction(Database1);
若没有实在意思,建议传递将数据库的指针,
如:DLL库的函数:
MyFunction(TDatabase *Database)
{
Query1->DataBase = Database;
......
}
调用时:
MyFunction(Database1);
#8
楼上的兄弟,这样好像不行吧。TQuery::DabaBase 属性是不可用的。而且我的BDE句柄留出来可以供 BCB 6.0 使用,要是不传句柄你让我传什么?
#9
关注一下
#10
哪位大哥帮帮忙!拜托。
#11
的确. __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;
你可以试试改成将
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;
#12
为什么不用数据模块呢?用数据模块不就可以实现连接共享?
#13
我的程序之所以要传递数据库的句柄,就是为了实现
动态创建数据库实例
将数据库的名字(DatabaseName)给记录集(TTable, TQuery)
然后,访问记录集。
直接传递进来的数据库对象的名字、或者指针都是不好用的。
并且我创建的数据库不需要再次连接,只是共享句柄,然后“广播”他的“数据库名字”罢了。
那么我用数据库模块,在我这种情况之下又该如何实现共享呢?
动态创建数据库实例
将数据库的名字(DatabaseName)给记录集(TTable, TQuery)
然后,访问记录集。
直接传递进来的数据库对象的名字、或者指针都是不好用的。
并且我创建的数据库不需要再次连接,只是共享句柄,然后“广播”他的“数据库名字”罢了。
那么我用数据库模块,在我这种情况之下又该如何实现共享呢?
#14
经过测试,是可以的.
//--- 以下是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;
}
//--- 以下是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;
}
#15
我用该相同的方法,但是说是找不到数据库名。
不过,还是谢谢各位了。
不过,还是谢谢各位了。
#1
还有,我用的是 SQL Server 配置的 ODBC, BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
对写 ==> 多谢 !
#2
还有:
我用的是 MS SQL Server,配置 ODBC
BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
我用的是 MS SQL Server,配置 ODBC
BCB 5.5 和 BCB 6.0 的句柄会不会冲突?
对写 ==> 多谢 !
#3
人呢?
#4
我不知道 帮你顶一下
#5
唉!帮你up吧,我还没有用BC连接过数据库
#6
期待
#7
为什么要传递将数据库的句柄 MDatabase->Handle 呢?我实在想不通.
若没有实在意思,建议传递将数据库的指针,
如:DLL库的函数:
MyFunction(TDatabase *Database)
{
Query1->DataBase = Database;
......
}
调用时:
MyFunction(Database1);
若没有实在意思,建议传递将数据库的指针,
如:DLL库的函数:
MyFunction(TDatabase *Database)
{
Query1->DataBase = Database;
......
}
调用时:
MyFunction(Database1);
#8
楼上的兄弟,这样好像不行吧。TQuery::DabaBase 属性是不可用的。而且我的BDE句柄留出来可以供 BCB 6.0 使用,要是不传句柄你让我传什么?
#9
关注一下
#10
哪位大哥帮帮忙!拜托。
#11
的确. __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;
你可以试试改成将
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;
#12
为什么不用数据模块呢?用数据模块不就可以实现连接共享?
#13
我的程序之所以要传递数据库的句柄,就是为了实现
动态创建数据库实例
将数据库的名字(DatabaseName)给记录集(TTable, TQuery)
然后,访问记录集。
直接传递进来的数据库对象的名字、或者指针都是不好用的。
并且我创建的数据库不需要再次连接,只是共享句柄,然后“广播”他的“数据库名字”罢了。
那么我用数据库模块,在我这种情况之下又该如何实现共享呢?
动态创建数据库实例
将数据库的名字(DatabaseName)给记录集(TTable, TQuery)
然后,访问记录集。
直接传递进来的数据库对象的名字、或者指针都是不好用的。
并且我创建的数据库不需要再次连接,只是共享句柄,然后“广播”他的“数据库名字”罢了。
那么我用数据库模块,在我这种情况之下又该如何实现共享呢?
#14
经过测试,是可以的.
//--- 以下是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;
}
//--- 以下是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;
}
#15
我用该相同的方法,但是说是找不到数据库名。
不过,还是谢谢各位了。
不过,还是谢谢各位了。