客户端查询时如何判表在服务器端是否存在(如果问题解决了会再加分,各位大侠帮帮忙) ( 积分: 50 )

  • 主题发起人 主题发起人 cgy2005
  • 开始时间 开始时间
C

cgy2005

Unregistered / Unconfirmed
GUEST, unregistred user!
问题:
我我在服务器端创建了一个服务器应用程序,数据模块里面是两个Query(Query1,Query2)和两个dataprovider(dataprovider1,dataprovider2)
Query属性里的databasename分别指向两个我在BDE里加的数据库的别名
在客户端我用的是TSocketConnect和TClientdataset组件连接远程数据库的
现在服务器里的数据库有我要查找的表的时候一切正常,但时如果没有我要查找的表就会有异常出现,提示没有某天的表存在

客户端出错的地方:
ClientDatahis.close;
ClientDatahis.CommandText:= 'Select 时间,电压值 From ' +mydbfName
+ ' Where (变电所 =''' + BDSName + ''');//mydbfName是我要找的表的表名
ClientDatahis.open;//没有表的时候一open就出异常了,我该如何先判断服务器端是否有这个表,有的话我再open,没有的话我就提示没有当天的记录
我的想法:
原来在单机版本的情况下我是这样判断表是否存在的
MydbfPath := MainPath + 'HISDATA/' + inttostr(Year) + '/mydbf/';//要找的表的路径
MydbfName := 'BusVolt' + S1 + S2;//要找的表的名字
if FileExists(MydbfPath+MydbfName) then
begin
......
end;
现在在C/S模式下我的客户端不能用FileExists(MydbfPath+MydbfName)判断了,我该如何判断我远程服务器是否有我要找的表
如果有就继续执行,没有就提示没有这天的记录,我的想法是用
MydbfName := 'BusVolt' + S1 + S2;//要找的表名
fileexit:= gettablename(MydbfName);//调用函数返回一个布尔值
if fileexit then
begin
......
end;

Function TCrossHairForm.gettablename(MydbfName:string):boolean;
var
mytabel:string;
begin
try
......
result:=....;//这里的语句该如何写呢,如何去在远程服务器里找这个表是否存在然后再返回结果呢
except
result:=false;
end;
end;






 
问题:
我我在服务器端创建了一个服务器应用程序,数据模块里面是两个Query(Query1,Query2)和两个dataprovider(dataprovider1,dataprovider2)
Query属性里的databasename分别指向两个我在BDE里加的数据库的别名
在客户端我用的是TSocketConnect和TClientdataset组件连接远程数据库的
现在服务器里的数据库有我要查找的表的时候一切正常,但时如果没有我要查找的表就会有异常出现,提示没有某天的表存在

客户端出错的地方:
ClientDatahis.close;
ClientDatahis.CommandText:= 'Select 时间,电压值 From ' +mydbfName
+ ' Where (变电所 =''' + BDSName + ''');//mydbfName是我要找的表的表名
ClientDatahis.open;//没有表的时候一open就出异常了,我该如何先判断服务器端是否有这个表,有的话我再open,没有的话我就提示没有当天的记录
我的想法:
原来在单机版本的情况下我是这样判断表是否存在的
MydbfPath := MainPath + 'HISDATA/' + inttostr(Year) + '/mydbf/';//要找的表的路径
MydbfName := 'BusVolt' + S1 + S2;//要找的表的名字
if FileExists(MydbfPath+MydbfName) then
begin
......
end;
现在在C/S模式下我的客户端不能用FileExists(MydbfPath+MydbfName)判断了,我该如何判断我远程服务器是否有我要找的表
如果有就继续执行,没有就提示没有这天的记录,我的想法是用
MydbfName := 'BusVolt' + S1 + S2;//要找的表名
fileexit:= gettablename(MydbfName);//调用函数返回一个布尔值
if fileexit then
begin
......
end;

Function TCrossHairForm.gettablename(MydbfName:string):boolean;
var
mytabel:string;
begin
try
......
result:=....;//这里的语句该如何写呢,如何去在远程服务器里找这个表是否存在然后再返回结果呢
except
result:=false;
end;
end;






 
大家来帮帮忙啊,我急死了
 
给服务器加个方法判断有无表,客户端调用这个方法了事
 
to realLearning:
你能不能把客户端和服务器的代码都帖出来,我不太会写,万分感谢!!
 
恕我直言,你的观念太陈旧了,根据我的经验,你一定是搞硬件的‘房客’。
数据库可没有这么干的。相同的数据记录应该放在一个表里,而不是每天一个表(只有直接使用文件系统才会采用这种手段提高数据访问的效率)。
你只要简单改一下,你会发现:数据库解决这个问题比文件系统还要简单。相反,在数据库中每天增加一张表倒是件困难和不可思议的事。
1)固定这张表的名字,不要再去判xx表是否存在;
2)你的这张表一定有一个时间字段,确保这个字段包含日期信息(在DELPHI中无非是NOW、DATE、TIME这三个函数的选用问题);
3)提取数据时可以采用提取指定时间段数据的方法
Select * from xx where [时间字段]>=:dt1 AND [时间字段]<:dt2
parameters('dt1').Value := [起始时间]
parameters('dt2').Value := [终止时间]
或全部提取后,用Filter过滤出你所需要时间段的记录。
4)提取之后通过判段RecordCount属性就可知道提取到了几条记录, 当然不必再去关心"是否有文件"的问题啦.
 
有一件事我没想到,也许记录数据的程序不是你在做,而系统总体设计是由一个数据库的门外汉做的,你只是编写其中一部分,而无权改结构,那么,这样,非常简单:
因为在DELPHI中,"错误"是程序流程的一种手段, 就在你的客户端解决
ClientDatahis.close;
ClientDatahis.CommandText:= 'Select 时间,电压值 From ' +mydbfName
+ ' Where (变电所 =''' + BDSName + ''');//mydbfName是我要找的表的表名
try
ClientDatahis.open;//没有表的时候一open就出异常了,
//不出异常就是成功;
return true;
except
ShowMessage('表不存在!');
//虽然这不确切,还有其它错误会引起except,当然也有办法知道,但付出的劳动和你们的系统设计不相称,不值得!
return false;
end;
//========没必要
//我该如何先判断服务器端是否有这个表,有的话我再open,没有的话我就提示没有当天的记录
//========
另外,服务端也可采用同样的办法加以判断,但是还需要多做一个远程函数去通知ClientDataSet,有些多此一举.
最正规的做法当然是:远程函数查问,在服务程序中用专门的函数获取数据库中表的清单,如TADOConnection的GetTableNames方法,...然后察看是否存在...然后向客户端返回函数结果. 虽说不是很复杂,但好象对你来说,麻烦了点儿,有时间再去研究吧.
祝你好运!
 
to q2000:我下面调用服务器端的函数出了问题。
客户端:
TableName := 'Act_' + strmonth + strday;//得到表名
SConnection.Connected := True;
fileexit := SConnection.AppServer.fileexit(TableName);//调用服务器端的函数的时候出错了
if fileexit then
begin
...............
end;

服务器端:
function THHES_CX_DBS1.fileexit(var TableName: string): boolean;//传进来一个表名TableName到目录下去找
var
mydbfName, mydBfPath: string;
begin
//Database1.GetTableNames();
mydBfPath := 'H:/mydbf/';
mydbfName := TableName;
//如果存在这张表则进行如下计算。
if fileexists(mydBfPath + mydbfName) then
begin
result := true;
end
else
result := false;
end;

我该如何去调用服务器端的函数呢
 
不讨论你的服务函数是否正确(可以通过调试找出错误),关键是 你是如何建立服务函数的。从贴的内容来看,好象是你自己写的函数(当然,肯定不是别人写的)。我是说,那不符合服务函数的规范,缺IAppServer接口,等等问题......
请到view ->
type library中去建立函数,这样简单点儿。
在IAppServer中建立方法,如:
TableIsExist
注意参数,如:
TblName BSTR [in] //代入参数
ErrMsg BSTR * [in,out] //返回参数
res VARIANT_BOOL * [out,retval] // <-- 这样是函数返回值
方法建立之后,更新.
然后去你的rdm模块中,你应该能找到这个函数,并在其中把你的代码填进去。
然后......在DELPHI中运行服务程序,便可通过断点检查你的代码是否有错了。
当然,激活这段代码,需要你的客户端运行起来,并去调此服务函数。
OK!

 
q2000真是狠!
技术高,而且诲人不倦!
现在这样的高手越来越少了!
 
首先要在服务器端注册一个接口供调用:
function TNew_AutoData.GetTableList: OleVariant;
var
I: Integer;
DBNames: TStrings;
begin
{ Return a list of all of the database names to the client }
DBNames := TStringList.Create;
try
SQLConnection1.GetTableNames(DBNames,false);
Result := VarArrayCreate([0, DBNames.Count - 1], varOleStr);
for I := 0 to DBNames.Count - 1do
Result := DBNames;
finally
DBNames.Free;
end;
end;

客户端调用:
var
I: Integer;
TaBNames: OleVariant;
begin
RemoteServer.Connected := True;
TaBNames := RemoteServer.AppServer.GetTableList;
listbox1.items.clear;
if VarIsArray(TaBNames) then
for I := 0 to VarArrayHighBound(TaBNames, 1)do
Listbox1.items.Add(TaBNames);
//这样所有表的名称已经在listbox1中了,想怎么查找都很简单了吧!
end;
 
谢谢大家我再试试
 
后退
顶部