直接这样行不?我没试过。
ClientDataSet1->Params[0]->AsString = Edit1->Text;
ClientDataSet1->Params[0]->AsString = Edit1->Text;
解决方案 »
- cxTreeList中onGetDisplayText事件的疑问,太奇怪了,求高手解疑!在线等啊。分不够可再加!
- 连接ACCESS出现未指定的错误,连接SQL没有问题
- 获得打开窗口中图标在整个屏幕中的坐标
- 非delphi 问题,怎么改文件夹属性?
- 『每帖必结』请教:为什么我TRY了它还是要报错???
- 简单的问题,up有分!
- 大家好!问一个ado+sql2000问题!
- what mean about'identifier'
- 如何截取一个字副串中到空格为止的部分。如asd ad 中如何截取asd?
- 我真笨,看不懂,请各位大师看看????
- 分数用不了,给大家一些!
- 怎么才能使serverSocket每一秒种轮寻检查客户端发送过来的数据
在ClientDataSet这右键 Fetch Params, 就可以得到参数的正确定义了。
如果在 Server那边打开 ADOQuery->Params时没有东东,先删除Strings中内容,指定Connection后再填入Strings,就可以看到Params。我的建议是最好不要人为加参数,常会出现你的问题。还有一个 当参数内容包含中文时, 参数的 size会被不正确定义。要在BeforeGetRecords时对Params的Size修正, Params->Size = Length( Params->Value );
:pp1 DataType - ftString, ParamType - ptInput
:pp2 DataType - ftString, ParamType - ptInput
:pp3 DataType - ftString, ParamType - ptInput
:pp1 DataType - ftString, ParamType - ptInput
:pp2 DataType - ftString, ParamType - ptInput
:pp3 DataType - ftString, ParamType - ptInput
我也试过WideString, 可能没有试对. 我再试试, 有结果回来汇报.我开始也在服务端的ADOQuery也建立了参数, 错误依然. 后来删掉, 不用代码方式填写参数值是可以正确得到结果的. 这说明即使服务端的ADOQuery需要参数,也不必在ADOQuery定义,可以在ClientDataSet中定义.
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中的,看看是不是你关了它。
size好像要跟数据库设计时字段的size要一样。
现把我的看法贴出,供大家参考。如果有哪位高手能提出可行的方法找出问题的原因,我还会去试验。
可以得到如下的简单结论: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”?
你是不是也可以这样做。:)
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;我从来没用过存储过程,呵呵。
你特别强调的可能有解,在服务端ADOxxx->Parameters->Attributes中有个选项paNullable可以试试
delphi中
ADOQuery.Parameters.ParseSQL(ADOQuery.SQL.Text, True).
我因为一定要采用Free线程模式, 不能使用BDE, 只能使用ADO. 只好继续调试、试验,试图找出原因。今天有些进展:1. 当3个参数的值有空串时(长度为0或不为0的空格串),出现错误:“Parameter 对象被不能正确地定义。提供了不一致或不完整的信息。”。这个错误我可以避免(不提供空串参数。没办法的办法。呵呵),所以我的开发可以继续。
也许选项paNullabl可以解决这个问题。我去试试。
我也在服务器端定义了相应的参数。2. 当存储过程中返回一个空的记录集时,出现新的错误,提示说没有返回的数据集。这点很可恶。因为如果参数不正确(口令等),我是需要返回空的记录集的。而且,在其它场合也会有空的记录集,可现在的现象却不支持通过存储过程中返回一个空的记录集!这是不是ADO的特点?!如何解决?
注:我在存储过程中返回记录集是通过在存储过程中执行一个可以得到记录集的select语句。使用 MS SQL Server。
to newyj(老鬼):我看看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。
非常感谢!
我刚看到你的回复. 我研究研究先.