Delphi10.4 ClientDataSet调用SQL Server存储过程参数异常空格问题求助
Delphi 10.4 Android调用SQL Server存储过程参数乱码/空格问题解决
问题场景
使用Delphi 10.4开发Android程序,通过TSQLConnection(DataSnap)搭配TClientDataSet调用SQL Server存储过程时,参数传递后尾部出现大量异常空格/乱码,执行update table1 set ddate = @date时触发“从字符串转换日期和/或时间时失败”错误。
原Delphi代码
var orderNo,date:string; orderNo := ''; date := '2024-02-04 00:00:00'; With QSysDataSet do begin close; commandText:= 'exec S_SignSR :orderNo,:Date'; Params.ParamByName('orderNo').dataType := ftstring; Params.ParamByName('orderNo').ParamType := ptInputOutput; Params.ParamByName('orderNo').size := 20; Params.ParamByName('orderNo').value := orderNo; Params.ParamByName('Date').dataType := ftstring; Params.ParamByName('Date').ParamType := ptInputOutput; Params.ParamByName('Date').size := 30; Params.ParamByName('Date').value := date; execute; end.
对应SQL Server存储过程
create procedure S_SignSR @orderNo varchar(20) output, @date varchar(30) output as begin update table1 set ddate = @date end
已尝试无效方案
- 显式设置参数Size时,参数长度额外增加1,尾部填充空格
- 跳过设置Size,参数仍存在多余空格
- 使用
AsString赋值出现乱码,甚至参数值被截断 - 转换字符串编码(WideString/AnsiString/UTF8Encode)均无效
- 仅在存储过程中用
substring(@date,1,19)截取可临时规避,但未解决参数传递本身问题
可行解决方案
方案1:匹配正确的参数数据类型
不要用ftString处理日期参数,改用SQL Server对应的日期类型;字符串参数匹配存储过程的varchar类型,使用ftVarChar而非ftString(ftString对应SQL的char,会自动补空格)。
修改后代码:
With QSysDataSet do begin close; commandText:= 'exec S_SignSR :orderNo,:Date'; // 处理orderNo:对应varchar(20)输出参数 Params.ParamByName('orderNo').dataType := ftVarChar; Params.ParamByName('orderNo').ParamType := ptInputOutput; Params.ParamByName('orderNo').size := 20; Params.ParamByName('orderNo').value := orderNo; // 处理Date:直接用日期类型而非字符串 Params.ParamByName('Date').dataType := ftDateTime; Params.ParamByName('Date').ParamType := ptInput; // 存储过程中未修改@date,无需Output Params.ParamByName('Date').value := StrToDateTime(date); execute; end;
同时修改存储过程的参数类型(如果ddate是datetime类型):
create procedure S_SignSR @orderNo varchar(20) output, @date datetime -- 改为datetime类型,移除output as begin update table1 set ddate = @date end
方案2:使用标准存储过程调用方式
不要用exec拼接命令,而是设置CommandType为ctStoredProc,让组件自动处理参数映射,避免手动拼接导致的编码问题。
修改后代码:
With QSysDataSet do begin close; CommandType := ctStoredProc; CommandText := 'S_SignSR'; // 直接指定存储过程名 // 重置参数并配置 Params.Clear; // 添加orderNo参数 Params.CreateParam(ftVarChar, 'orderNo', ptInputOutput).Size := 20; Params.ParamByName('orderNo').Value := orderNo; // 添加date参数 Params.CreateParam(ftDateTime, 'date', ptInput).Value := StrToDateTime(date); Execute; end;
方案3:调整DataSnap连接的字符集
在TSQLConnection的连接参数中,设置CharacterSet为与SQL Server数据库匹配的值(如UTF-8或SQL_Latin1_General_CP1_CI_AS),避免编码转换时产生乱码。
可在连接字符串中添加:
CharacterSet=UTF8;
或在设计时,直接在TSQLConnection的Params属性中设置CharacterSet对应值。
方案4:修正存储过程参数的Output属性
存储过程中@date参数被设为output,但实际未对其赋值修改,属于冗余设置。改为input参数后,组件无需预留输出缓冲区,可避免额外的空格/乱码。
修改后的存储过程:
create procedure S_SignSR @orderNo varchar(20) output, @date varchar(30) -- 移除output属性 as begin update table1 set ddate = @date end
内容的提问来源于stack exchange,提问作者sky find
相关产品推荐
相关产品推荐

