直接这样行不?我没试过。
ClientDataSet1->Params[0]->AsString = Edit1->Text;

解决方案 »

  1.   

      参数定义要在服务器上指明,你的 ADOQuery建立后,参数列表都指定成String(它自动变成OleStr也就是WideString,你的错误所在)
      在ClientDataSet这右键 Fetch Params, 就可以得到参数的正确定义了。
      如果在 Server那边打开 ADOQuery->Params时没有东东,先删除Strings中内容,指定Connection后再填入Strings,就可以看到Params。我的建议是最好不要人为加参数,常会出现你的问题。还有一个 当参数内容包含中文时, 参数的 size会被不正确定义。要在BeforeGetRecords时对Params的Size修正, Params->Size = Length( Params->Value );
      

  2.   

    ClientDataSet1建立参数---------怎样建立的?应该用fetch params!
        :pp1 DataType - ftString, ParamType - ptInput
        :pp2 DataType - ftString, ParamType - ptInput
        :pp3 DataType - ftString, ParamType - ptInput
        
        
      

  3.   

    ClientDataSet1建立参数---------怎样建立的?应该用fetch params!
        :pp1 DataType - ftString, ParamType - ptInput
        :pp2 DataType - ftString, ParamType - ptInput
        :pp3 DataType - ftString, ParamType - ptInput
        
      

  4.   

    首先多谢各位!我没有使用fetch params, 可能是错误发生的原因. 我再试试, 有结果回来汇报.
    我也试过WideString, 可能没有试对. 我再试试, 有结果回来汇报.我开始也在服务端的ADOQuery也建立了参数, 错误依然. 后来删掉, 不用代码方式填写参数值是可以正确得到结果的. 这说明即使服务端的ADOQuery需要参数,也不必在ADOQuery定义,可以在ClientDataSet中定义.
      

  5.   

    回答、关心这个贴子的朋友可参考C++Builder中的http://www.csdn.net/expert/Topic/134/134381.shtm
      

  6.   

    补充: 我把TADOQuery换成BDE的TQuery, 一切都正常. 可我就是想用ADO!
      

  7.   

    没用过存储过程的参数,我是这样用参数的。
    with ClientDataSet1 do
    begin
      Close;
      Params.Clear;
      Params.CreateParam(ftDateTime,'ParamName1',ptInput);
      Params.Createparam(ftString, 'ParamName2', ptInput);
      ...
      CommandText := 'you SQL';
      Params.ParamByName('ParamName1').Value:=Date1.DateTime;
      Params.ParamByName('ParamName2').Value:='String Value';
      Open;
     
    end;
    还有ADO控件中,有个ParamCheck: Boolean,它是控制是否将Params组合到SQL中的,看看是不是你关了它。
      

  8.   

    还有像comanche(太可怕) 所说,参数size问题,
     size好像要跟数据库设计时字段的size要一样。
      

  9.   

    to: copy_paste(paste), 我用select语句也没问题. 怪!
      

  10.   

    今天再去试验各种方法, 结果依然! 我决定修改设计方案,避开这个问题。
    现把我的看法贴出,供大家参考。如果有哪位高手能提出可行的方法找出问题的原因,我还会去试验。
    可以得到如下的简单结论:1. 尽管应用服务器端的ADOQuery/Query的SQL中需要参数, 但如果在对应的ClientDataset中定义了参数后, ADOQuery/Query中可以不再定义参数. 
    2. 在设计时, 在ClientDataset用Fetch params的方法可以简化参数的定义过程, 但其结果与手工逐个定义是一样的, 而且用Fetch params时还需要在ADOQuery/Query中定义参数.现在的现象:
       不论在应用服务器端使用ADO的ADOQuery/ADOStoreproc, 都会出现同样的错误.
       1. 在应用服务器端使用ADOQuery, 不管是否在ADOQuery中定义参数, 都会出现“Parameter 对象被不能正确地定义。提供了不一致或不完整的信息。”的错误。
       2. 在应用服务器端使用ADOStoreproc, 需要在ADOStoreproc中也定义参数(可以自动地得到4个参数,其中一个时返回值), 在ClientDataset用Fetch params的方法得到参数定义。也会出现“Parameter 对象被不能正确地定义。提供了不一致或不完整的信息。”的错误。   
       3. 使用BDE的Query就完全正确。
       4. 修改SQL语句成“Select ... ... where field1=:pp1, field2=:pp2, field3=:pp3”,使用ADOQuery没有出现问题。
       5. 修改SQL语句成“EXEC P_R_GetList :pp1, :pp2, ''”,使其只有2个参数,使用ADOQuery没有出现问题。
       6. 修改参数的顺序,错误依然。
       7. 不论是否出现错误,都可以在应用服务器的程序中显示出看似正确的参数值(将它们截取后显示在Edit控件中)。
    特别强调:
       使用ADOQuery, 设计时在ClientDataSet参数的属性窗口中填入这3个参数的值,则可以得到需要的数据集,正确!!但如果在代码中改变参数的值,就会出错!
    我判断:
       A. ClientDataSet参数的类型在以下2种方式中有所区别:
          1. BCB在IDE环境中, 手工在ClientDataSet的参数属性窗口中填入参数的值;
          2. Client端程序运行时, 通过代码给参数赋值。这时跟踪参数的DataType没有改变。
       
       B. 可能是ClientDataSet的TParams类与TADOQuery的TParameters类在参数传递时,有兼容性的问题。而且这个错误还是在TADOQuery控件与Windows的ADO API处。因为这个错误信息居然是中文!!
       
       C. 在Client端程序中通过代码给参数赋值时, 是不是改变了参数的Value->Type(其实没有这个属性,但在参数属性窗口中可以设置)。如何指定“Value->Type”?
          
       特别强调:
       使用ADOQuery, 设计时在ClientDataSet参数的属性窗口中填入这3个参数的值,则可以得到需要的数据集,正确!!但如果在代码中改变参数的值,就会出错!
    我判断:
       A. ClientDataSet参数的类型在以下2种方式中有所区别:
          1. BCB在IDE环境中, 手工在ClientDataSet的参数属性窗口中填入参数的值;
          2. Client端程序运行时, 通过代码给参数赋值。这时跟踪参数的DataType没有改变。
       
       B. 可能是ClientDataSet的TParams类与TADOQuery的TParameters类在参数传递时,有兼容性的问题。而且这个错误还是在TADOQuery控件与Windows的ADO API处。因为这个错误信息居然是中文!!
       
       C. 在Client端程序中通过代码给参数赋值时, 是不是改变了参数的Value->Type(其实没有这个属性,但在参数属性窗口中可以设置)。如何指定“Value->Type”?
          
       
      

  11.   

    nononono我以前用多层的时候,用ADO+SocketConnection,ClientDataSet Insert不上记录,并且delete,edit也不行,只能browse,你猜我怎么办:Server加一个方法:把参数值传过来,再在服务端中过滤处理,服务端处理的时候就直接用SQL来做,客户端再Refresh。哈哈,没办法。
    你是不是也可以这样做。:)
    client:
      ClientDataSet1.AppServer.IWantToExec('param1,param2');
    server:
    procedure IWantToExec(const Value: WideString);
    var
      Param1,Param2: string;
    begin
      Param1 := Copy(Value, 1, pos(',', Value) -1);
      param2 := Copy(Value, pos(',', Value + 1), 100);
      with ADOCommand do
      begin
        CommandText := Format('EXEC P_R_GetList %s, ''%s''', [param1,param2]);
        ExecSQL;
      end;
    end;我从来没用过存储过程,呵呵。
      

  12.   

    to copy_paste(paste):你在服务器加方法更新是不好的,虽然说没什么不对,但我个人认为有点不规范,再说我的用法跟你一样,从没出现过问题。出现多表选择时我都是在 BeforeUpdateRecord时更新。to nononono: 我用我的Delphi试了几百次了,都不会出现你的错,真不明白,我记得以前我常有这错的。可能是个顺序上的问题。不过我是建议在服务器上做Params, 我在服务器的编写时间远大于在服务机上的时间..
    你特别强调的可能有解,在服务端ADOxxx->Parameters->Attributes中有个选项paNullable可以试试
      

  13.   

    调用this->ClientDataSet1->Params->Items[0]->AsString调用
    delphi中
     ADOQuery.Parameters.ParseSQL(ADOQuery.SQL.Text, True). 
      

  14.   

    to comanche(太可怕):
    我因为一定要采用Free线程模式, 不能使用BDE, 只能使用ADO. 只好继续调试、试验,试图找出原因。今天有些进展:1. 当3个参数的值有空串时(长度为0或不为0的空格串),出现错误:“Parameter 对象被不能正确地定义。提供了不一致或不完整的信息。”。这个错误我可以避免(不提供空串参数。没办法的办法。呵呵),所以我的开发可以继续。
        也许选项paNullabl可以解决这个问题。我去试试。
        我也在服务器端定义了相应的参数。2. 当存储过程中返回一个空的记录集时,出现新的错误,提示说没有返回的数据集。这点很可恶。因为如果参数不正确(口令等),我是需要返回空的记录集的。而且,在其它场合也会有空的记录集,可现在的现象却不支持通过存储过程中返回一个空的记录集!这是不是ADO的特点?!如何解决?
       注:我在存储过程中返回记录集是通过在存储过程中执行一个可以得到记录集的select语句。使用 MS SQL Server。
    to newyj(老鬼):我看看ParseSQL的含义,再去试试。多谢!多谢!
      

  15.   

    同一个问题的C++Builder版的贴子:http://www.csdn.net/expert/topic/134/134381.shtm
      

  16.   

    你试过ParseSQL的方法了吗?我的做法是在服务定义一个方法,然后在客户端调用该方法:
    function TCommandObj.RunStoredProc(const sUserName, sPassWord,
      sStoredProcname: WideString; Paramters: OleVariant): WideString;
    var
     i:integer;
     sSql:string;
     e:Exception;
    begin
      spUserName:=sUserName;
      spPassWord:=sPassword;
      result:='';
     sSql:='';
     for i:=VarArrayLowBound(Paramters,1) to VarArrayHighBound(Paramters,1) do
       sSql:=sSql+':'+intTostr(i)+',';
     sSql:=copy(sSql,1,length(sSql)-1);
     with ADOStoredProc1 do begin
       ProcedureName:=sStoredProcname;
       Parameters.ParseSQL(sSql,true);
      for i:=VarArrayLowBound(Paramters,1) to VarArrayHighBound(Paramters,1) do
         ADOStoredProc1.Parameters.Items[i].Value:=Paramters[i];
       try
        ExecProc;
        SetComplete;
       except
        on e:Exception do begin
         result:=e.Message;
         SetAbort;
        end;
       end;
     end;
    end;
    客户端:
    procedure TForm1.Button2Click(Sender: TObject);
    var
     c:ICommandObj;
     vParam:OleVariant;
    begin vParam:=VarArrayOf(['18','18','18']);
     SocketConnection1.Connected:=true;
     SocketConnection1.appserver.RunStoredPro('u1','p1','SP_TEST_HZB2',vParam);
    end;
    我不知道如何用Delphi在Oracle数据库中执行SQL语句来调用存储过程,所以我用了一个TStoredProc,动态给他赋值.
    这个存储过程没有返回值,因此我没有对返回值进行处理,但在BCB版的帖子提到“用OleVariant的用于返回 DataSetProvider的数据”是一个挺好的解决办法,要用的话,需要加一个返回的参数vdata,然后在ExecProc后面加vdata:=DataSEtProvider.data。
      

  17.   

    to: hzb(Explorer) 
    非常感谢! 
    我刚看到你的回复. 我研究研究先.