Delphi SQL.Add()使用返回字符串的自定义函数抛出不兼容性错误

时间:2015-02-26 10:27:10

标签: sql delphi

我有以下代码,它基于许多变量构造一个SQL语句:

SQL.Add('SELECT CDbl(Answer) as An FROM v_Outcomes_FirstLastOneYear ' +
  'WHERE ' + GetTool(ReportGrid.Cells[col, 0]) + ' ' +
  'AND (Collector = ' + QuotedStr('Patient') + ') ' +
  'AND (Question=' + GetQuestion(ReportGrid.Cells[col, 0]) + ') ' +
  'AND (Answer is not null) ' +
  'AND (Answer <> ''null '') ');

if Copy(ReportGrid.Cells[col, 0], Length(ReportGrid.Cells[col, 0]), 1) = '1' then
  SQL.Add('AND ('+GetTPoint(first)+') ')
else
  SQL.Add('AND ('+GetTPoint(second)+') ');

SQL.Add('ORDER BY CDbl(Answer)');

ReportGridTStringGrid)的第一行已填充了一系列字符串,例如'Peds phys 1''Peds phys 2'。最后一个数字是1或2。

变量&#39;首先&#39;和第二个&#39;进一步定义的字符串。

col是一个整数 - 此语句构造为for循环的一部分,该循环遍历每个列并使用与标题对应的数据填充每一行。

GetTool()GetQuestion()GetTPoint()是我定义的功能。 GetTPoint()的代码如下:

function GetTPoint(timepoint: string): string;
begin
  if (timepoint = '0') or (timepoint = 'discharge') then
  begin
    if timepoint = '0' then
      Result := 'FirstAxData=''TRUE'' and DischargeData=''FALSE''';
    if timepoint = 'discharge' then
      Result := 'DischargeData=''TRUE'' and FirstAxData=''FALSE''';
  end
  else
  begin
    timepoint := FormatFloat('0', StrToInt(timepoint)*30.4368);
    Result := '[Date] BETWEEN ([Date of First CPC]+' + timepoint +
      ')-61 AND ([Date of First CPC]+'+timepoint+')+61';
  end;
end;

每个自定义函数都相似,只返回一个字符串。 GetTool()GetQuestion()都正常工作但GetTPoint()会引发以下编译错误:

  

E2010不兼容的类型:&#39; string&#39;和&#39;程序,无类型指针或   无类型参数&#39;

有谁知道为什么会抛出这个?

1 个答案:

答案 0 :(得分:6)

您显示的代码显示在您正在操作的查询对象的with语句中。像这样:

with SomeQuery do begin
  SQL.Add(...);
  ...
end;

您可以单独引用SQL属性,因为with语句将查询对象的成员带入当前范围。这意味着所有其成员,包括First方法(用于选择第一个查询结果)。在with语句范围内引入的任何内容都将隐藏在早期作用域中引入的同名内容。这包括您说的其他地方声明的first变量。

当你有表达式GetTPoint(first)时,编译器会将名称first解释为引用查询方法,而不是变量。该方法不是字符串,并且调用它不会返回字符串,因此编译器会正确地抱怨。

最佳解决方案是停止使用with。它只是为代码引入了脆弱性。如果您只是必须继续使用with,请重命名您的first变量,以便它不会干扰稍后带入范围的名称。无法引用已被另一个范围隐藏的局部变量。 (如果first是全局的,您可以使用单位名称对其进行限定,但应避免使用全局变量,几乎与with语句一样多。)