我有以下代码,它基于许多变量构造一个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)');
ReportGrid
(TStringGrid
)的第一行已填充了一系列字符串,例如'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;
有谁知道为什么会抛出这个?
答案 0 :(得分:6)
您显示的代码显示在您正在操作的查询对象的with
语句中。像这样:
with SomeQuery do begin
SQL.Add(...);
...
end;
您可以单独引用SQL
属性,因为with
语句将查询对象的成员带入当前范围。这意味着所有其成员,包括First
方法(用于选择第一个查询结果)。在with
语句范围内引入的任何内容都将隐藏在早期作用域中引入的同名内容。这包括您说的其他地方声明的first
变量。
当你有表达式GetTPoint(first)
时,编译器会将名称first
解释为引用查询方法,而不是变量。该方法不是字符串,并且调用它不会返回字符串,因此编译器会正确地抱怨。
最佳解决方案是停止使用with
。它只是为代码引入了脆弱性。如果您只是必须继续使用with
,请重命名您的first
变量,以便它不会干扰稍后带入范围的名称。无法引用已被另一个范围隐藏的局部变量。 (如果first
是全局的,您可以使用单位名称对其进行限定,但应避免使用全局变量,几乎与with
语句一样多。)