2016-08-23 64 views
3

使用参数时,我有这个简单的代码来检查,如果在一个表中存在记录,但它总是会返回一个运行时错误:错误ADOQuery

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

我的代码是这样的:

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; 

表卡领域条形码类型为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来处理此类工作。

感谢大家的帮助。

+3

看样子你打算重用这个查询其他东西。试着在'Close'后面将'Parameters.Clear'操作从底部移动到顶部。 –

+0

@JerryDodge我刚刚尝试过,它没有帮助。我想你在哪里谈论Parameters.Clear; ? – GuidoG

+0

@GuidoG是的,这就是我的意思,编辑。 –

回答

3

以下内容并不打算成为q的完整答案,而是为了跟进我的评论:“您所要做的就是检查表单的DFM并将原始ADoQuery的属性与未共享的属性进行比较。答案应该在于差异(s)“,而你的回答是非共享查询是动态创建的。

您的两个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; 

过你......

+0

谢谢,我明天会试试这个,因为现在是午夜。 – GuidoG

+0

@GuidoG:没有probs - 在这里11,所以我知道这种感觉。 – MartynA

+0

@GuidoG:就我个人而言,我很同情这样的想法,即对于随机出现并且很少出现问题的问题,想出一个MCVE可能非常困难。顺便说一句,万一它不是很明显,我想你可以使用上面的代码来捕获在发生问题时在一个except块中的共享查询的属性。 – MartynA