我使用的是Delphi XE7,而我们的大型遗留应用程序之一仍然将BDE与Paradox表一起广泛使用。我知道BDE已过时,但我们对此应用程序别无选择。
该应用程序当前在运行时,启动时设置BDE别名。它使用BDE提供的标准默认会话,并使用“ TSession.AddStandardAlias”添加别名,并引用数据模块中定义的许多表。
现在,我需要能够在应用程序的运行中稍后更改别名引用的文件夹路径,但是发现它存在问题。基本上,它似乎可以工作,但是在更改别名后,它仍会以某种方式引用先前的路径。甚至“ TSession.GetAliasParams”也会报告新路径,但是Bde.DBTables会发生错误,因为它试图访问不再存在的先前路径。
鉴于应用程序很大,我在以下示例项目中重现了类似的问题。如果有人愿意尝试,这是一个非常简单的应用程序,仅包含主要形式。您需要设置两个文件夹,并将任何Paradox表放到一个文件夹中,然后在“编辑”框中指定该文件夹的路径,然后按“设置别名路径”按钮,这将设置别名,然后将其写入按钮下方的标签,用于告诉您别名所指的路径。然后,“查找表”按钮和编辑框使用“ TSession.GetTableNames”查找表的存在。
最简单的方法是设置两个文件夹“ C:\ TEMP \ testBDE \ path1”和“ C:\ TEMP \ testBDE \ path2”,然后将任何Paradox表拖放到path1中,然后在运行应用程序时按“ Set(设置)”。别名路径”按钮,然后按“查找表”按钮,它将报告表存在。
然后更改别名以引用路径2,该路径为空,它报告指向路径2,但也报告该表存在。然后很容易将表从路径1移动到路径2,然后它将报告该表不存在。
任何建议将不胜感激。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
Bde.DBTables;
const
myAlias = 'ALIAS1';
function getPathFromAlias(tempAlais : String ): String;
var
MyStringList : TStringList;
i, k: integer;
tempStr, newDirectory: String;
begin
newDirectory:='';
MyStringList := TStringList.Create;
try
Session.GetAliasParams(tempAlais,MyStringList);
{ fill stringlist with driver names }
for i := 0 to MyStringList.count-1 do
begin
tempStr:= uppercase(trim(MyStringList.Strings[i]));
k := pos('PATH=', tempStr);
if k > 0 then
begin
delete(tempStr,1, k+4);
newDirectory:=tempStr;
end;
end;
finally
MyStringList.Free;
end;
result:=newDirectory;
end;
procedure setAliases( apath : String);
var
MyStringList : TStringList;
begin
(*
MyStringList := TStringList.Create;
try
MyStringList.Add( 'PATH='+apath);
MyStringList.Add( 'ENABLE BCD=FALSE');
MyStringList.Add( 'DEFAULT DRIVER=PARADOX');
Session.ConfigMode := cmSession;
if Session.IsAlias( myAlias) then
Session.ModifyAlias( myAlias, MyStringList)
else
Session.AddStandardAlias( myAlias, apath, 'PARADOX');
Session.ConfigMode := cmSession;
finally
MyStringList.Free;
end;
*)
Session.ConfigMode := cmSession;
if Session.IsAlias( myAlias) then
Session.DeleteAlias( myAlias);
Session.AddStandardAlias( myAlias, apath, 'PARADOX');
Session.ConfigMode := cmSession;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
setAliases( Edit1.Text);
Label1.Caption := getPathFromAlias( myAlias);
end;
function TableExists(const aDataBaseName, aTableName:string): Boolean;
var
TableNames: TStringList;
begin
TableNames:=TStringList.Create;
try
Session.GetTableNames(aDatabaseName,'',True,False,TableNames);
Result:=(TableNames.IndexOf(aTableName)<>-1);
finally
TableNames.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
temps : String;
myTable : TTable;
begin
if TableExists( myAlias, Edit2.Text) then
Label2.Caption := 'Exists'
else
Label2.Caption := 'Not found'
end;
end.
您需要先关闭会话,然后再更改别名属性,然后再再次打开它:
procedure TForm1.Button1Click(Sender: TObject);
begin
Session.Close;
setAliases( Edit1.Text);
Label1.Caption := getPathFromAlias( myAlias);
Session.Open;
end;
问题不在于无法识别路径更改,而是如果对使用的别名进行更改,则无法识别,因为测试程序中的这种情况说明了这一点:
即,如果您要做的第一件事就是更改路径,那么别名确实会反映该更改的路径。问题是,一旦使用了别名,对路径的更改将不会随后反映出来。
通过关闭会话并重新打开它,可以确保正确“重置”别名。
在您的实际应用程序中,这可能会导致连锁反应,在关闭并重新打开会话后需要重新打开数据库连接,尽管这是我的推测。
作为关闭会话以在运行时修改别名的替代方法,另一种方法可能是添加具有所需属性的新别名,并将数据库连接重定向到该替代别名。
显然,这也将导致断开并重新连接所有重定向到该备用别名的数据库和查询。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句