AaG7xNnrgbzeyqc5woPS / ydh_glxt

0 stars 0 forks source link

Bugs: y_qygl_crm_20220831.zip 版本开始发生“数据库链接错误”! #1

Open AaG7xNnrgbzeyqc5woPS opened 2 years ago

AaG7xNnrgbzeyqc5woPS commented 2 years ago

〇、问题描述:

  1. 用户报告bugs,发现新版的程序(y_qygl_crm_20220831.zip)无法链接数据库,登录界面都不会出来!
  2. y_qygl_crm_20220902.7z 版本同样无法链接数据库,问题同上面的一样。

一、问题分析解决过程 一

  1. 程序更改过的地方可能会有错,这几个地方进行过更改 a. 增加三个表格,是不是对方数据无法自动增加这三个表格,自动增加表格程序可能有误 b. 邮件传输,下载可能有错误,改进,使用 7zip多卷压缩,100K一个文件,邮件上传果然快多了。邮局目前不会扫描7zip文件,安全性也提高了。
  2. 同用户视频沟通,视频观看用户电脑,启动时候会报错,系统性的错误。这个错误我没有遇到过,但是用户经常遇到,数据库配置错误就会出现这个提示。用户这条经验很重要。
  3. 想到我在程序设计的时候,需要在设计状态下链接数据库,我增加了一条ODBC配置记录, ydh_local,这样我在设计的时候就能链接上数据库了,方便设计。
  4. 根据 上一条信息,在用户电脑上配置ODBC ydh_local记录,登录,DBE配置项变成绿色的,说明配置正确,链接成功。
  5. 用户配置好 ODBC ydh_local后,运行程序还是不行,bug 依旧。老的程序能登录,正常!
  6. 我在我的开发电脑上 删除 ODBC ydh_local配置项目,新程序依然能启动,证明ODBC ydh_local 同故障无关,不重要,这个只在开发期期间起作用。

总结:

  1. :+1: 这个错误,大概率跟整个数据库的链接有关系,比如缺某一个数据库。再就可能跟数据库内缺某些表格有关
  2. 该错误跟 ODBC的设置没有关系
AaG7xNnrgbzeyqc5woPS commented 2 years ago

二、问题分析解决过程二

1. 研究程序的启动登录次序,熟悉下程序

  1. 主程序如下:
    Application.Initialize;
    Application.Title := '潜龙贸易助手';
    if LoginUser.login then
    begin
    Application.CreateForm(TForm_Test, Form_Test);
    end;
    Application.Run;
  2. function TUser.Login: boolean

    
    function TUser.Login: boolean;
    begin
    result := false;
    
    //----建立dm_main数据窗口
    //----建立数据库联结 (包括BDE,和ADO)
    if not ConnectDB then exit;

// === 具体使用时,要打开这一部分,由用户输入用户名及口令! if myLogin(Funame,FUID) then begin dmmain.ForDebugUser(Funame,FUID); //用于处理调试时,修改实际用户,如超级用户 FBenQiyeName := getobjectmc('select max(qymc) from adm.qyxxb where qylx = 0 and sfxs = ''T'''); Fbqybh := getobjectbh('select max(qybh) from adm.qyxxb where qylx = 0 and sfxs = ''T''');

RightCheck.Init('ydh_local', FUID, FUName);
FxmRight := GetUser_xmRight;

dmmain.InitAfterLogin('ydh_local', Fxmright.def_xmmc, Fuid, FUName);

if assigned(application.MainForm) then
begin
  application.ShowMainForm     := true;
  application.MainForm.Visible := true;
end;

result := true;

end

end

4. function ConnectDB: boolean;

function ConnectDB: boolean; begin result := false; if not assigned(dmMain) then dmMain := TdmMain.Create(nil);

dmMain.ADOConnection1.Connected := true; result := dmMain.ADOConnection1.Connected;

//连接成功后立即升级数据库 updateDB._UpdateDB; updateDB_202208.update_db_202208; // 增加 三个表,图纸表,图纸类型表,产品图纸对应表,以及一些约束关系

end;



## 2. 阅读上面的程序总结下:
1. 主程序最先调用:LoginUser.login 
2. TUser.Login 最先调用 ConnectDB
3. dmMain 最先创建 dmMain,然后 启动 ADOConnection1 链接,最后升级数据库。
4. :heart: 所以主要查看 ConnectDB 函数
AaG7xNnrgbzeyqc5woPS commented 2 years ago

三、问题分析解决过程三

1. 创建一个空数据库 ydh_test,进行测试

  1. 使用 “Microsoft SQL 企业管理器” 进行如下操作, 将 空数据库备份文件 crm_wwy_zero 恢复到数据库 ydh_test
  2. 在注册表编辑器中,更新当前数据为“ydh_test”,将数据库切换到 ydh_test
  3. 启动 最新版 y_qygl_crm 程序,可以登录。奇怪的是,产品目录里面居然有数据,而且还有我昨天新做的测试数据,说明这个产品目录表格链接到 老的 数据库中(topbang),这是前几前用的数据库
  4. 使用 “Microsoft SQL 企业管理器” 查看 ydh_test数据库,adm.cpmc 表的确没有没有数据,说明空数据库恢复没有错。
  5. 使用 “Microsoft SQL 企业管理器” ,将 topbang数据库进行“脱机”,这样确保没有应用程序链接到该数据库中。
  6. 使用 delphi 打开 新版程序 y_qygl_crm,提示找不到 topbang,说明 程序的配置参数还记得 topbang数据库,并且在开发状态的时候,需要链接 topbang 数据库。
  7. 点击错误提示对话框,再保存应用,(这个时候相关的属性就会删除,并且会将一些表格的打开属性关闭,缺省就不会打开数据库表格,也不会链接数据库)。编译应用,完全过正确
  8. 运行 y_qygl_crm 程序,不会再提示出错信息,可以正常登录。并且数据库是空的,登录用户只有administrator,密码是ydh。产品名称表也是空的。
  9. :lady_beetle: 岗位设置模块,有一个提示信息:“岗位表不空,不能添加缺省岗位,清先清除已有岗位”。但是可以看到已经添加了缺省岗位。分析下原因,这应该是添加两次缺省岗位。这是一个小bug。改进方案一:“添加缺省岗位”的过程,应该做成“密等性”,“无状态”。为了保持函数内的 提示信息,可以用一个参数来控制,缺省为false不提示重复添加,如果要提示,设置为true。这样就完美啦!
  10. :100: 上一条岗位设置模块中的bug已经修改完成,:100: 测试成功! :100: Perfect! 代码如下:
    procedure Add_Default_gw_1(isShowmessage: boolean = false);  //增加缺省岗位方案一。
    var s: string;
    i : integer;
    begin
    s := 'select * from adm.gwb';
    if not isEmpty(s) then
    begin
    if  isShowmessage then
      raise Exception.Create('岗位表不空,不能添加缺省岗位。确定要添加缺省岗位,请先清除已有的岗位!')
    end  
    else
    for i := low(gw1) to high(gw1) do
    begin
      s := ' insert into adm.gwb (gwbh,gwmc) values ('
           + inttostr(i) + ','
           + quotedstr(gw1[i]) + ')';
      execsql(s);
    end;
    end;

2. 总结:

1.:100: 数据库链接问题的测试方法:使用 “Microsoft SQL 企业管理器”将无关数据库“脱机”处理,使用注册表编辑器,切换 数据库链接到新的数据库,启动程序,程序应该能正常链接数据库,登录,程序内的数据确保是新数据库种取出来的。如果有链接错误,立即能发现!

  1. :100: 消除上面错误的诀窍:在“脱机”无关的数据库的情况下,先使用 注册表编辑器切换到 新数据库。然后使用delphi 打开源代码,如果有数据库链接错误会提示,并且会自动修复。保存源码,并且编译,就可以得到数据库链接正确的程序!
AaG7xNnrgbzeyqc5woPS commented 2 years ago

四、问题分析解决过程四

1. 继续深入分析 ConnectDB 函数,找到更多模块

function ConnectDB: boolean;
begin
  result := false;
  if not assigned(dmMain) then
    dmMain := TdmMain.Create(nil);

  dmMain.ADOConnection1.Connected := true;
  result := dmMain.ADOConnection1.Connected;

   //连接成功后立即升级数据库
  updateDB._UpdateDB;
  updateDB_202208.update_db_202208;   // 增加 三个表,图纸表,图纸类型表,产品图纸对应表,以及一些约束关系

end;

查看 dmMain 数据模块,可以发现跟链接数据库相关的,最关键就是 控件 ADOConnection1: Tydh_ADO_BDE_Connect

Tydh_ADO_BDE_Connect = class(Tydh_ado_Connect)
Tydh_ado_Connect = class(TADOConnection)
TydhRegister = class(TComponent)  

2. TydhRegister = class(TComponent)

处理windows注册表,在注册表中保存配置程序的配置信息,包括,软件的注册信息,数据库链接信息。

1. 注册码


## 3.  TInitDatabase = class(TExecSqlBatch)
  在完全空白的 MS SQL SEVER 服务器上建立 用户和数据库

(* -------------------------------------------- 功能: 在完全空白的 MS SQL SEVER 服务器上建立 用户和数据库

  1. 建立数据库的初始口令
  2. 建立3个用户(系统管理员,数据库拥有者dbo,ydh用户),初始化时做一次即可
  3. 改变数据库的口令一次,口令保存在注册表中。
  4. 主过程,建立一个数据库,初始化数据库。
  5. 注册软件,用户输入公司名称、简称、软件序列号进行验证

引用控件 TExecSqlBatch TydhRegister

*)


## 4. TydhConfigConnect = class(TComponent)
**功能:**
 -  1, 在网络上查找sql server 2000 数据库服务器,并注册在注册表中!
 -  2,:heart:  建立ODBC_DSN  interface ,并将ODBC_DSN名("ydh_qygl_Don't_delete_me")注册在注册表中!
 -  3, :100: 测试ODBC_DSN自动建立功能:删除 "ydh_qygl_Don't_delete_me" ODBC 配置,再启动程序 y_qygl_crm.exe, 可以发现 配置项又出现了!

**引用:**
       -  TydhRegister
       -  TODBC_Add_DSN
       -   TListSQLServers

## 5. ODBC_Add_DSN

功能: 本控件TODBC_Add_DSN,根据指定参数建立ODBC数据源 引用: odbc_API ---这是一个 odbc dll库的封装

AaG7xNnrgbzeyqc5woPS commented 2 years ago

五、问题分析解决过程五

delphi 7 中的 package ,dll的调试方法:

Local tab

Use this page to run and debug projects.

Host application

Enter the path to an executable file. (Click Browse to bring up a file-selection dialog.)
If the current project is a DLL (Windows) or a shared object (Linux), use this edit box to specify a host application that calls it.
You can also enter the name of any executable that you want to run in the debugger. Then press Load to load the executable. The executable will be paused at its entry point. If there is no debug information at the entry point, the CPU window will be opened. Select Run|Run (F9) to run the executable.

If you want to run the project that you have open, there is no need to enter anything in the Host Application edit box.
AaG7xNnrgbzeyqc5woPS commented 2 years ago

六、问题分析解决过程六

1. 程序测试一

AaG7xNnrgbzeyqc5woPS commented 2 years ago

七、总结:

AaG7xNnrgbzeyqc5woPS commented 2 years ago

八、后记

AaG7xNnrgbzeyqc5woPS commented 2 years ago

九、又有新发现

AaG7xNnrgbzeyqc5woPS commented 2 years ago

十、完美解决

1. 解决方法:

ADOConnection1: Tydh_ADO_BDE_Connect; Tydh_ADO_BDE_Connec 控件重新调试 Tydh_ado_Connect 控件重新调试 当然是从基础控件一个一个调试。最后调试 Tydh_ADO_BDE_Connect

2. Tydh_ado_Connect 关键过程:

这个函数关键,如果处理的不对,会提示内部错误,猜到这个函数是关键后,一步一步跟踪可以解决问题。

procedure Tydh_ado_Connect.SetConnected(Value: Boolean);
begin
   if Value then  //当前要打开连接,这之前需要做
  begin
    if ConfigConnect then    //配置连接成功?
    begin
      SetConnectParam;             //设置ADO连接参数
      ActiveOtherConnect(Value);   //激活BDE连接
    end;
  end
  else
  begin
    //关闭连接需要做......
    ActiveOtherConnect(Value);   //先关闭BDE连接
  end;

  inherited;    //再调用 祖先类的方法,关闭或者打开ADO的连接

end;

3. Tydh_ado_Connect 测试

4. 针对 Tydh_ADO_BDE_Connect 同样的测试