在ADOQuery中使用参数时出错

时间:2016-08-23 20:25:14

标签: delphi parameters delphi-7 ado

我有这个简单的代码来检查表中是否存在记录,但它总是返回运行时错误:

  

参数类型错误,超出可接受的范围,或者是   相互冲突。

我的代码是:

function TDataModuleMain.BarCodeExists(barCode: string): boolean;
begin
   if ADOQuerySql.Active then
     ADOQuerySql.Close;

   ADOQuerySql.SQL.Clear;
   ADOQuerySql.SQL.Text := 'select count(1) from Card where BarCode = (:TestBarcode)';
   ADOQuerySql.Parameters.ParamByName('TestBarcode').Value := barCode;

   ADOQuerySql.Open; // HERE THE RUNTIME ERROR APPEARS

   Result := ADOQuerySql.Fields[0].AsInteger = 1;
   ADOQuerySql.Close;
   ADOQuerySql.Parameters.Clear;
end;

表Card中的字段BarCode的类型为nvarchar(100)

在调试中,我看到参数已创建,并使用正确的值填充 在sql server management studio中运行查询也可以。

我也找到了这个How to pass string parameters to an TADOQuery?并使用答案中的代码检查了我的代码,但我在这里看不到任何问题。
AdoQuery Error using parameters对我没有帮助。

毫无疑问,我错过了一些非常简单的东西,但我现在还没有看到它。

编辑:我根据评论中的建议尝试了一些事情:

.ParamCheck := True (default)  
.Parameters.ParamByName('TestBarcode').DataType := ftString  
.Parameters.ParamByName('TestBarcode').DataType := ftWideString  

然而,这些都没有奏效。

使用非共享AdoQuery的帮助是什么,而且没有任何错误就完成了这项工作。我现在正在使用它作为解决方案,但我仍然在好奇地看着共享的AdoQuery究竟是什么问题。

编辑:找到问题的根源。

我使用MartinA提供的功能来检查动态创建的查询和共享的AdoQuery,我发现了一个区别。
共享的AdoQuery填充了此属性:

ExecuteOption := [eoExecuteNoRecords]

并且动态创建的查询没有 由于此属性未在设计时设置,因此我没有看到它。 将属性清除为[]后,共享的AdoQuery再次工作 我将转而使用非共享AdoQuery进行此类工作。

感谢大家的帮助。

1 个答案:

答案 0 :(得分:3)

以下内容并不是对您的q的完整答案,而是跟进我的评论“您需要做的就是检查表单的DFM并将原始ADoQuery的属性与未共享的ADoQuery进行比较。答案应该在差异“和您的回复中,即非动态查询是动态创建的。

两个ADOQuerys之间的行为差​​异没有涉及“伏都教”。这只是捕捉实际差异的问题。

因此,您需要自己调试问题的是一些代码来比较两个组件的属性,即使它们中的一个或两个是动态创建的。在两个组件上使用以下例程将使您能够做到这一点:

function TForm1.ComponentToString(AComponent : TComponent) : String;
var
  SS : TStringStream;
  MS : TMemoryStream;
  Writer : TWriter;
begin
  //  Note:  There may be a more direct way of doing the following, without
  //  needing the intermediary TMemoryStream, MS
  SS := TStringStream.Create('');
  MS := TMemoryStream.Create;
  Writer := TWriter.Create(MS, 4096);

  try
    Writer.Root := Self;
    Writer.WriteSignature;
    Writer.WriteComponent(AComponent);
    Writer.FlushBuffer;
    MS.Position := 0;
    ObjectBinaryToText(MS, SS);
    Result := SS.DataString;
  finally
    Writer.Free;
    MS.Free;
    SS.Free;
  end;
end;

告诉你......