如何動態獲得TADOStoredProc的參數? 適用于SQL and Oracle(100分)

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

coolzew

Unregistered / Unconfirmed
GUEST, unregistred user!
TADOStoredProc控件,在指定ProcName后,點擊Params后會自動生成所需參數.
請問是調用了什么方法獲得的?
現動態生成TADOStoredProc,問如何才能在指定ProcName后,自動得到Paramters.
(以上均指SQL Server)

要求對Oracle也能適用最好.
 
我查了源程序,里面有个方法,但不是公开的
它是在procname改变后就调用一次
prepare时如果参数个数为0也会调用一次

-----
http://www.8421.org
 
原以為這里有問必答,沒想到高手少之又少^^^^^^^^^
 
我同事今天试了,对sql server,根本无需另外的处理
adostoredproc1.ProcName := xxx
后直接可以 Parameters.ParamByName ...
参数是自动刷新的
 
dqyound 兄:
謝謝你的回答, 我的方案是三層的.而且我希望是通用的(希望Oracle也能
適用).此外三層架構你有試過嗎?
源代碼我早已看過了,問題有二:
一.此方法為何不公開.
二.在SQL的早些版本中,會出現問題,Delphi并不能正確得到Params.
SQL Server中的解決方法我已找到,可Oracle中誰有好的解決思路
呢???????????????
我公司從來都是動態創建所有DB控件的.
 
这些参数信息都在系统表中,看看sys用户下的内容,找找文档应该能否解决
ADOQuery.Parameters.RefreshList 不知道有没有用
 
這個不會不了了之吧???????
看來大富翁中的真漢子越來越少.^_^
qdyoung兄: 你的測試是無法通過的.多謝了.
再過兩天,若再無人就答就收場了.
 
//TADOStoredProc控件,在指定ProcName后,點擊Params后會自動生成所需參數.
//請問是調用了什么方法獲得的?
adostoredproc.parameters.refresh; //肯定行,我就是这么做的
注意:你必须在设计时将ADOSTROEDPROC的存储过程名及PARAMETERS的属性全部删除,即
保存初始状态

 
不用ADO的StoredProc这样写
用ADO同理:
dm.PUBSPA.Close;
dm.PUBSPA.StoredProcName:='sp_addchannel_sell_info';
dm.PUBSPA.Params.Clear;
dm.PUBSPA.Params.CreateParam(ftstring,'@vsell_id',ptinput);
dm.PUBSPA.Params.CreateParam(ftCurrency,'@vtotal_money',ptinput);
dm.PUBSPA.Params.CreateParam(ftCurrency,'@vclean_money',ptinput);
dm.PUBSPA.Params.CreateParam(ftfloat,'@vtotal_number',ptinput);
dm.PUBSPA.Params.CreateParam(ftstring,'@vclient_id',ptinput);
dm.PUBSPA.Prepare;
ADO的StoredProc的参数不一样
 
创建Tadostoredproc后,再在应用层定义一个接口,
方法:edit/Add to interfalce.. 写一个函数,传递参数,调用存储过程。
这个我的一个实例(三层),看看有没有帮助,SQL SERVER与ORACLE都运行过。
function Tsms.smsproc(const procname: WideString;
paranum: OleVariant): OleVariant;
var //定义接口
sendcount, i: integer;
destmobile, tmp: string;
SL: TStringList;
begin
with ADOSP1 do
begin
ProcedureName := procname;
Parameters.Refresh;
destmobile := paranum[0];
parameters[2].Value := paranum[1]; //内容
parameters[3].Value := paranum[2]; //标识
SL := TStringList.Create;
SL.CommaText := destmobile; //CommaText 返回分隔后的字符
sendcount := sl.Count;
if sendcount = 1 then
begin
tmp := '9' + copy(destmobile, 2, 10);
parameters[1].Value := tmp;
Prepared;
ExecProc;
end
else
begin
for i := 0 to sendcount - 1 do
begin
tmp := sl.Strings;
tmp := '9' + copy(tmp, 2, 10);
parameters[1].Value := tmp;
prepared;
ExecProc;
end;
end;
end;
end;

 
begin
ADOSpMain.ProcedureName:='insertCategory';
adospmain.Parameters.Refresh; [gold]//<-就是这个[/gold]
adoconnection.BeginTrans;
for i:=0 to lbcategory.Items.Count-1 do
begin
adospmain.Parameters.ParamByName('@s_id').value:=i;
adospmain.Parameters.ParamByName('@category').value:=label1.Caption; //即类别名称如人员类别等
adospmain.Parameters.ParamByName('@content').value:=lbcategory.Items;
adospmain.ExecProc;
end;
adoconnection.CommitTrans;
end;
sbInfor.SimpleText :='保存完毕!';
 
這几天忙著加班,沒來BBS沒有想到這么朋友來光臨,實在是高興不已.
我已經做了比較詳細的測試,現將結果公布如下,想必對各位會有所幫助:
一: BDE下TStoredProc
在BDE下使用TStoredProc時,調用TStoredProc的Prepare來獲得參數是十分不可靠
的.Borland并未公開這些方法.原因是Delphi自帶的這些方法會存在與DBMS的版本
的沖突問題.我在Delphi4 加 SQL Server 7下能夠通過Prepare來獲得正確參數.但
在Delphi5(6) + SQL Server2000下并不能正確得到參數,ParamType不對.
所以考慮到程序的通用性,不見議使用些方法,至于qdyoung兄所說的只要對存儲名
賦值的做法是行不通的.不知各位是否知道在SQL Server(6.5以上的版)中自帶有一個
存儲過程可以獲得TStoredProc的參數.用此方法CreateParam是最安全的.在Oracle中
我只做了几個簡單的測試,通過了.但我想也存在同樣的問題.(Oracle 8.0.7+Delphi6)
二:ADO下的TADOStoredProc
測試表明在ADO下調用Param.Refresh是可以正確得到所有參數,且沒有什么問題.這與
Microsoft的驅動有關.如果你用ADO可以考慮些方法,畢竟這樣代碼可以簡化許多.

在本問題結束之時,我要感謝以下几個同仁:
a.qdyoung,zbsfg 謝謝你們的參與和測試.
b.hnyangbin 謝謝你的代碼范例.
c.IT书生 你的做法和我們的做法相似,三層似乎這種方法是The Best.


 
只有平均分了,分數不多,心意到就行了.不知可否?
 
后退
顶部