三层结构中,存储过程的问题?(100分)

  • 主题发起人 主题发起人 micro73
  • 开始时间 开始时间
M

micro73

Unregistered / Unconfirmed
GUEST, unregistred user!
开发环境:前台win98+delphi6 update packet 2+ado, 后台win2k server + ms sql2000 server
在SQL上有两个存储过程(一个Copy一批记录,一个只Copy一条记录,参数相同且对同一表进行操作),
我在中间层放置了一个几个TADODataSet和一个TADOStoredProc,通过TADOConnection连结到后台,
然后在中间层建立了一个函数:
procedure TLargeData.CopyRecords(ProcName, mth1, mth2: OleVariant);safecall;
begin
with ADOStoredProc1 do
begin
ProcedureName:=ProcName;
Prepared:=True;
Parameters.ParamByName('@YearMonth1').Value:=mth1;
Parameters.ParamByName('@YearMonth2').Value:=mth2;
ExecProc;
end;
end;
我的目的是在客户端给该函数传递三个参数,根据需要调用不同的存储过程。现在的问题是:
1、如果我直接在TADOStoredProc中指定ProcedureName(即在上述函数中取消ProcedureName:=ProcName;),
我必须点击Parameters属性对话才可以正常使用,否则会出现:Parameters '@YearMonth1' no found
的错误提示。
2、如果我不在TADOStoredProc中指定ProcedureName(即在上述函数中指定),那么就会出现:
Parameters '@YearMonth1' not found的错误提示。

请问出现错误的原因是什么,如何解决。
 
with ADOStoredProc do
begin
Connection:=ADOConnection; //链接数据库
Close;
ProcedureName:=XXXXXXX;
Parameters.Clear;
Parameters.CreateParameter('NO_TEXT', ftString, pdInput, 20,Edit1.Text );
..............
try
ExecProc;
except
.............
end;
end;
 
to 白衣书生:
你的方法可以,在发贴之前我就已经查过以前的贴子,上面有你这样的方法但我没有采用。
因为我手头没有相资料,所以虽然知道一些用法,但还是不完全明白。
另外,如果我用try...except...end将错误屏蔽掉,那么在except后面我是用result将错误
返回到客户端好还是直接在此处理异常好呢?
 
自动生成参数的办法应该可以避免上述的问题
 
Parameters.CreateParameter();这个你可以查阅delphi的帮助。 一看就会明白的。

>>如果我用try...except...end将错误屏蔽掉,那么在except后面我是用result将错误
>>返回到客户端好还是直接在此处理异常好呢?
这个看你的需要了。
这是我的在服务端的一段代码:
procedure TNT_Server.TEXT_APP(var TE_Array: OleVariant; out App_Result: OleVariant);
begin
with ADOStoredProc do
begin
...............
...............
Parameters.CreateParameter(.........);
Parameters.CreateParameter(.........);
try
ExecProc;
App_Result:=1; //成功
except
App_Result:=0; //失败
..............
end;
end;
.........
end;

客户端是这样的:
var TEArray,AppResult:OleVariant;
.............
try
DM_Form.SocketConnection.AppServer.TEXT_APP(TEArray,AppResult);
..........
if AppResult=0 then
begin
MessageBox(Handle,'操作失败! 请与系统维护员联系! ','提示信息',MB_OK+MB_ICONINFORMATION);
Exit;
end;
.............
finally
.............
end;

当然你还可以自定义异常来捕捉, 返回你所需要的异常信息。
 
to qinmingzsj:
如何自动生成参数,能举个例子吗?
 
[:)] Parameters.CreateParameter 就是自动生成参数
 
to jrq:
你说的我当然知道,而且以前的贴子上有很多例子。可能是你没明白我的意思,
我是想在中间层通过一个函数调用多个存储过程。而且这些存储过程的参数相同或
不同(这个都好办),但参数个数不同的时候呢?
 
执行存储过程不用这么费力吧。呵呵

试试这个?

exec StroProc para1, prar2, prar3
就当成一个 SQL语句执行一下行了
 
procedure TLargeData.CopyRecords(ProcName, mth1, mth2: OleVariant);safecall;
begin
with ADOStoredProc1 do
begin
ProcedureName:=ProcName;
///////////加
Parameters.refresh;
///////////////////
Prepared:=True;
Parameters.ParamByName('@YearMonth1').Value:=mth1;
Parameters.ParamByName('@YearMonth2').Value:=mth2;
ExecProc;
这样应该就可以了,你试一试
end;
end;
 
to wzca:
你的方法当然可以,而且在某些场合我也采用了。不过我总觉得它不是一个好办法。
这种做法有点象以前的单层或两层结构,你认为呢?
 
to christin:
你运行你的代码了吗?如果可以,我一开始就这样做了(具体原因你运行一下就知道了)。
 
我的是这样的
with dataconnect.ADOStoredProc do begin
procedurename:='update_qiy';
parameters.Refresh;
parameters.ParamByName('@danwdm').Value:=dataset.fieldbyname('danwdm').AsString;
ExecProc;
end;
可以通过,而且三层跟这个没什么关系吧。
中间层申请数据,服务器提供数据,dataset接收中间层发送回数据,在做本地操作。
这个是我们三层的做法。对你帮助可能不大。
 
>>>在中间层通过一个函数调用多个存储过程。而且这些存储过程的参数相同或
>>>不同(这个都好办),但参数个数不同的时候呢?
找简单方法的话,就是多写函数,每个函数对应不同的一个存储过程。:)
或者在一个函数中通过传入的参数判断应该执行那个存储过程,如:
case Sto_Type of
1: begin
ProcedureName:='Z';Parameters.Clear;
Parameters.CreateParameter();
end;
2: begin
ProcedureName:='X';Parameters.Clear;
Parameters.CreateParameter();
end;
...............
end;
这样是最苯的可行的了。
 
to jrq:
你的方法真的可称得上最笨的了,不过我觉得可行就不一定了。因为不同的存储过程
所需传入的参数是可能不同的,也就是说一个函数在调用不同的存储过程的时候它自身的
参数是不同的。我有一个想法不知是否可行:
1、在后台数据库中建立一个存储各个存储过程名和参数的表
2、然后在中间层建立一个函数,根据客户端传入的存储过程名来动态建立一个调用
该存储过程的函数,当然此时的函数参数是不同的
3、客户端首先调用中间层的函数去建立一个函数,然后再调用这个被建立的函数。
to 白衣书生:
可能是我太贪心了,其实按我原来的用意问题已经解决了,不过现在我想扩大讨论,
你放心,你的那一份我一定少不了的,分不够可以再加。
to ALL:
请大家继承讨论。
 
你们不知道在SQL Server中有一个系统存储过程可以得到某个存储过程的参数吗?
想想你们方法都有问题?
只是Oracle中如何处理我不知道而已。




 
to coolzew:
你有什么好方法,可以介绍一下吗?
 
后退
顶部