Delphi XE10.4 使用unidac连接sqlserver2008编程,上传服务器,出了标题错误。
一、原因分析
1、屏幕显示CoUnInitialize has not been call.(CoUnInitialize还没有被调用)
2、unidac需要相关COM插件支持,需要初始化COM的调用。
二、问题解决
1、模块属性
看上图,在UniServerModule有一个AutoCoInitialize属性,将其它属性为True,编译即可。
2、代码解决
服务单元引入activex单元,然后在服务执行函数中加入CoInitializeEx,CoUnInitialize二个函数:
建议在连接数据的代码开始与结束时,使用二个函数:
procedure TUniMainModule.UniGUIMainModuleCreate(Sender: TObject);
//MainModule创建时连接数据库
var
ini:TIniFile;
dbProviderName,
dbUsername,
dbPassword,
dbPort,
dbServer,
dbDatabase:String;
begin
CoInitializeEx(NIL,COINIT_MULTITHREADED);
sMainPath:=ExtractFilePath(Paramstr(0)); // 获取执行程序的绝对路径
ini := TIniFile.Create(sMainPath+'iniFileconfig.ini');
//读参数值
dbProviderName:=ini.ReadString('SERVER_DAC', 'ProviderName','SQL Server');
dbUsername:=ini.ReadString('SERVER_DAC', 'Username','');
dbPassword:=ini.ReadString('SERVER_DAC', 'Password','');
dbPort:=ini.ReadString('SERVER_DAC', 'Port','');
dbServer:=ini.ReadString('SERVER_DAC', 'Server','');
dbDatabase:=ini.ReadString('SERVER_DAC', 'Database','');
ini.Free;
UniConnection1.ProviderName:=dbProviderName;//'SQL Server'; // 驱动类型
UniConnection1.Username:=dbUsername; //'XXX'; // 登录名
UniConnection1.Password:=dbPassword; //'XXXX'; // 登录密码
UniConnection1.Port:=strToInt(dbPort); // 1433; // 端口
UniConnection1.Server:=dbServer; //'LYHOO6JSQL2008'; //
UniConnection1.Database:=dbDatabase; //'XXXXX理_LC'; // 数据库名
UniConnection1.Connect; // 连接
CoUnInitialize;
if UniConnection1.Connected then
begin
UniServerModule().Logger.AddLog('数据库','连接数据库成功!');
end
else begin
UniServerModule().Logger.AddLog('数据库','连接数据库失败!');
end;
end;
三、机制说明
CoInitializeEx是 Windows提供的API函数,为当前线程初始化COM库并设置并发模式 。应用程序调用com库中的函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
在应用程序中使用COM库,至少要调用一次CoInitializeEx函数(通常也就调用一次)。如果传入参数的并发标志相同,单个线程也可以多次调用该函数,但后来有效的调用将返回 S_FALSE。在正常关闭COM库情况下,每一个CoInitialize 或者CoInitializeEx的成功的调用(也包含返回S_FALSE的调用),都必须用通Uninitialize函数来结束。
当UniServerModule模块中将AutoCoInitialize属性设置True时,编译后程序自动加入相关代码,执行上述二个函数了。



