Delphi:“参数对象定义不正确。提供的信息不一致或不完整。”

时间:2009-04-02 23:23:55

标签: sql-server delphi

我正在尝试将记录插入到3层数据库设置中的表中,并且中间层服务器在尝试将第一个参数添加到查询时,会将上面的错误消息生成为OLE异常。 / p>

我已经用Google搜索了这个错误,并且我一致地发现了相同的结果:它来自查询中某个字符串中的冒号,这是ADO的SQL解析器。这不是这种情况。任何地方都没有假冒的冒号。我已经检查并重新检查对象定义与我试图插入的表的模式。一切都结束了,这让我的同事难过。有谁知道还有什么可能导致这个?我在这里结束了我的智慧。

我正在使用Delphi 2007和SQL Server 2005。

13 个答案:

答案 0 :(得分:4)

我可以使用Delphi 2007和MSSQL Server 2008获得此错误,并找到了解决方法。 (这是相当糟糕的恕我直言,但也许它对你有用,如果你的是由同样的事情造成的。)

产生错误的代码:

with TADOQuery.Create(nil)
do try

   Connection := ADOConnection;

   SQL.Text := ' (SELECT * FROM Stock WHERE  InvCode = :InvCode ) '
              +' (SELECT * FROM Stock WHERE  InvCode = :InvCode ) ';

   Prepared := true;

   Parameters.ParamByName('InvCode').Value := 1;

   Open;  // <<<<< I get the "parameter object is...etc. error here.

 finally
   Free;
 end;

我找到了两种解决方法:

1)从SQL中删除括号,即:

   SQL.Text := ' SELECT * FROM Stock WHERE  InvCode = :InvCode  '
              +' SELECT * FROM Stock WHERE  InvCode = :InvCode  ';

2)使用两个参数而不是一个:

with TADOQuery.Create(nil)
do try

   Connection := ADOConnection;

   SQL.Text := ' (SELECT * FROM Stock WHERE  InvCode = :InvCode1 ) '
              +' (SELECT * FROM Stock WHERE  InvCode = :InvCode2 ) ';

   Prepared := true;

   Parameters.ParamByName('InvCode1').Value := 1;
   Parameters.ParamByName('InvCode2').Value := 1;

   Open;  // <<<<< no error now.

 finally
   Free;
end;

答案 1 :(得分:3)

我在搜索前面提到的Exception消息时发现了这个帖子。在我的情况下,原因是尝试将SQL注释/ * foo * /嵌入到我的query.sql.text中。

(我认为在我的探查器窗口中看到评论浮出过来会很方便。)

无论如何 - Delphi7讨厌那个。

答案 2 :(得分:2)

这是一个迟到的回复。就我而言,它完全不同。

我尝试将存储过程添加到数据库中。

Query.SQL.Text :=
'create procedure [dbo].[test]' + #13#10 +
'@param int ' + #13#10 +
'as' + #13#10 + 
'-- For the parameter you can pick two values:' + #13#10 + 
'-- 1: Value one' + #13#10 + 
'-- 2: Value two';

当我删除冒号(:)时它起作用了。因为它看到冒号作为参数。

答案 3 :(得分:1)

我遇到了你问题中描述的同样错误。我已将错误追溯到ADODB.pas - &gt; procedure TParameters.AppendParameters; ParameterCollection.Append(Items[I].ParameterObject).
通过使用breakppoints,在我的情况下通过一个参数填充错误,该参数应填充数据库中的DateTime字段,并且我从未填充参数。设置参数()。值:=''解决了问题(我也尝试过使用varnull,但是有一个问题 - 而不是在数据库中发送Null,查询发送1 - varnull的整数值)。

PS:我知道这是一个'迟到很晚'的答案,但也许有人会遇到同样的错误。

答案 4 :(得分:1)

我自己刚刚遇到这个错误。我正在使用Delphi 7使用TAdoQuery组件写入2003 MS Access数据库。 (旧代码)我的查询在MS Access中直接工作正常,但在Delphi中通过TAdoQuery对象失败。我的错误来自日期/时间值的冒号(对原始海报道歉)。

据我了解,Jet SQL日期/时间格式为#mm / dd / yyyy hh:nn:ss#(不需要0左边填充)。

如果TAdoQuery.ParamCheck属性为True,则此格式失败。 (谢谢海报!)两种解决方法是:a)将ParamCheck设置为False,或b)使用不同的日期/时间格式,即“mm / dd / yyyy hh:nn:ss”(带双引号)。

我测试了这两个选项,但它们都有效。

即使双引号日期/时间格式不是Jet日期/时间格式,Access也非常擅长灵活使用这些日期/时间格式。我还怀疑它与BDE / LocalSQL / Paradox(Delphi 7的原生SQL和数据库引擎)日期/时间格式有关(使用双引号,如上所述)。解析器可能被设计为忽略带引号的字符串(双引号是BDE LocalSQL中的字符串值分隔符),但在其他非本机日期/时间格式上可能会有些绊倒。

SQL Server使用单引号来分隔字符串,因此在写入SQL Server表(未测试)时可能会使用双引号而不是双引号。或许Delphi TAdoQuery对象仍然会绊倒。在这种情况下关闭ParamCheck可能是唯一的选择。如果您打算在代码中切换ParamCheck属性值,那么在启用它之前,通过确保SQL属性为空来节省一些处理时间,如果您不打算解析当前的SQL。

答案 5 :(得分:0)

如果我记得很清楚,你必须明确地将NULL值添加到参数中。如果您使用的是TAdoStoredProc组件,则应在设计时执行此操作。

答案 6 :(得分:0)

您使用的是线程吗?我似乎记得在ADO连接用于另一个同步查询时,当计时器事件启动查询时收到此错误。 (计时器每分钟检查一次“系统可用”标志)。

答案 7 :(得分:0)

您是否设置了参数的DataType,还是将其保留为ftUnknown?

答案 8 :(得分:0)

我也有同样的问题,但是使用动态命令(例如Update语句) 一些参数可能为NULL 我能让它工作的唯一方法是设置参数.DataType:= ftString和parameter.Size:= 1并且不设置值

cmdUpdate := TADOCommand.Create(Self);
try
  cmdUpdate.Connection := '**Conections String**';
  cmdUpdate.CommandText := 'UPDATE xx SET yy = :Param1 WHERE zz = :Param2';
  cmdUpdate.Parameters.ParamByName('Param2').Value := WhereClause;
  if VarIsNull(SetValue) then
  begin
    cmdUpdate.Parameters.ParamByName('Param1').DataType := ftString;
    cmdUpdate.Parameters.ParamByName('Param1').Size := 1;
  end else cmdUpdate.Parameters.ParamByName('Param1').Value := SetValue;
  cmdUpdate.Execute;
finally
  cmdUpdate.Free;
end;

答案 9 :(得分:0)

我今天刚刚在TADOQuery上遇到了这个错误,它有ParamCheck := False且在SQL中没有冒号。

以某种方式将 OLECMDEXECOPT_DODEFAULT 参数传递给TWebBrowser.ExecWB()导致了这个问题:

这显示了问题:

pvaIn := EmptyParam;
pvaOut := EmptyParam;
TWebBrowser1.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT, pvaIn, pvaOut);

这没有显示问题:

pvaIn := EmptyParam;
pvaOut := EmptyParam;
TWebBrowser1.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DONTPROMPTUSER, pvaIn, pvaOut);

答案 10 :(得分:0)

查询中的单个双引号也会引起我刚刚经历的错误,并且我根本不使用参数......

答案 11 :(得分:0)

尝试在SQL中使用时间值时会出现此错误,并且忘记使用QuotedStr()将其包装。

答案 12 :(得分:0)

我得到了同样的错误。原来,这是因为存储过程的参数被声明为varchar(max)。使它varchar(4000)并且错误消失。