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


  参数类型错误,超出可接受范围或
  彼此冲突。


我的代码是这样的:

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进行此类工作。

感谢大家的帮助。

最佳答案

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

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

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

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;


交给你...

10-02 13:25