TL;DR- 要使用默认 SP 参数值设置:
ADOStoredProc1.Parameters.ParamByName('@p_name').ParameterObject.Value := Unassigned
在德尔福代码中,我没有传递第二个参数我是
期望 SQL Server 应该采用它的默认值。
是的,你是。您在设计时使用了一个已经存在的参数,因此该参数作为 NULL 显式发送到 SQL Server。您可以通过检查 SQL 探查器来验证这一点。
If you must使用设计时参数,您可以在运行时删除它default参数旨在以其他方式使用或创建/分配它。例如(你可以为此制定一个通用方法):
var
Param: TParameter;
ParamName: WideString;
ParamValue: Variant;
UseDefaultParameter: Boolean;
begin
ParamName := '@p_name';
Param := ADOStoredProc1.Parameters.FindParam(ParamName);
UseDefaultParameter := True; // or False to assign a value
if UseDefaultParameter then
begin
if Assigned(Param) then
ADOStoredProc1.Parameters.Delete(Param.Index);
end
else
begin
ParamValue := 'boo!';
if Assigned(Param) then
Param.Value := ParamValue
else
ADOStoredProc1.Parameters.CreateParameter(ParamName, ftString, pdInput, 10, ParamValue);
end;
end;
否则,请勿使用设计时参数并根据需要在运行时创建参数。 IMO 更好的方法是使用本地TADOStoredProc
,在运行时创建它,分配参数,执行它,然后销毁它。
就我个人而言,我创建我的TADOStoredProc
在运行时并调用Parameters.Refresh() http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ADODB_TParameters_Refresh.html方法,它将从 SQL Server 查询(并创建)参数。然后我只需将值分配给我需要的参数即可。即使多了一次SQL Server,但在SP中添加新参数时维护起来还是很方便的。
如果未设置参数值,ADO 将启动exec
命令设置参数default
关键词。 IE
exec p_dummy_proc @p_id=1, @p_name=default
经过进一步挖掘,我发现问题实际上出在TParameter.SetValue
二传手。无法“清除”参数值:
procedure TParameter.SetValue(const Value: Variant);
begin
if VarIsEmpty(Value) or VarIsNull(Value) then <--
NewValue := Null
else
begin
...
end;
ParameterObject.Value := NewValue;
end;
您可以看到,如果您设置了Value
to NULL
or Unassigned
, ParameterObject.Value
将被设置为NULL
(但永远不会使用默认值)。
所以如果需要清除某个参数,并使用默认值,则需要直接设置TParameter.ParameterObject.Value
to Unassigned
:
if UseDefaultParameter then
SP.Parameters.ParamByName('@p_name').ParameterObject.Value := Unassigned
else
SP.Parameters.ParamByName('@p_name').Value := 'boo!'