2010-04-11 154 views
2

我有一个代码,检查加载窗体时的当前日期,执行一个简单的计算,并在Delphi中附加一个SQL。它适用于使用Delphi 7的Windows 7,使用Xp的另一台计算机上,但不使用Xp的其他三台计算机上。当表单加载时,它会显示“表达式中的类型不匹配”,并指向追加后的行。可能是什么问题呢?类型在Delphi 7中的表达不匹配在SQL附加

procedure TfmJaunumi.FormCreate(Sender: TObject); 
var d1, d2: TDate; 

begin 
d1:= Date; 
d2:= Date-30; 
With qrJaunumi do 
    begin 
     Open; 
     SQL.Append('WHERE Sanem_datums BETWEEN' + #39 + DateToStr(d1) + 
     #39 + 'AND' + #39 + DateToStr(d2) + #39); 
     Active := True; 
    end; 
end; 
+0

比较的区域设置的计算机上,首先把日期格式 – kludg 2010-04-11 12:07:08

+3

OT我知道,但我只是不能忍受看着很差格式代码..如果我回顾这段,我d让您修正缩进并将这些日期分配放在他们自己的行上。 http://jcl.delphi-jedi.org/documents/styleguide.html#4.3 – 2010-04-11 14:31:15

+0

改为使用QuotedStr#39 – 2010-04-11 16:58:11

回答

0

不幸的是,上述方法都无效,但解决方案是用“yy.mm.dd.”替换格式。而不是“yyyy.mm.dd.”,并添加单引号。奇怪的是,它表示格式是“yyyy.mm.dd.”到处。 代码看起来像现在这样:

procedure TfmJaunumi.FormCreate(Sender: TObject); 
var d1, d2: TDate; d3, d4, atd: String; 

begin 
    d1:= Date; 
    d3:= FormatDateTime('yy.mm.dd.',d1); 
    d2:= Date-30; 
    d4:= FormatDateTime('yy.mm.dd.',d2); 
    atd := ''''; 
    With qrJaunumi do 
    begin 
     Open; 
     SQL.Append('WHERE Sanem_datums BETWEEN'+ atd+d4+atd +'AND'+ atd+d3+atd+';'); 
     Active := True; 
    end; 
end; 
3

这几乎可以肯定这些计算机上的本地国际化的设置做 - DateToStr将在当地的日期格式(可能是MM/DD/YYYY或DD/MM/YYYY)返回一个字符串 - 和不同的地方你可能不是你所期待的。

我怀疑你会发现它没有工作的电脑认为他们在不同的国家/使用不同的国际化设置,它们的工作电脑。

更好的解决方案是使用FormatDateTime将日期转换为您的SQL Server安装将接受的标准格式,因此任何本地“国际化”设置都不会像这样产生干扰。

+0

我检查了服务器设置,日期格式在哪里可以进行更改,它们是相同的,但仍然错误不会消失。我甚至尝试过各种FormatDateTime选项。还有什么可以解决这个问题吗? – Demonick 2010-04-11 13:47:57

+0

@恶魔 - 好的,那么我们需要比较字符串。您可以在每种情况下获取发送到剪贴板的SQL.Strings属性的内容吗? (将ClipBrd添加到您的使用子句中,然后执行Clipboard.AsText:= SQL.Text)。或者甚至只是ShowMessage - 我们确实需要比较正在运行的和未运行的情况下生成的实际SQL。 :-) – robsoft 2010-04-11 14:15:19

4

您可以使用预准备语句来克服日期时间值的任何本地化问题。 DateToStr取决于客户端。如果服务器的本地化不接受日期格式,FormatDateTime可能会失败。

procedure TfmJaunumi.FormCreate(Sender: TObject); 
var 
    d1, d2: TDate; 
begin 
    d1:= Date; 
    d2:= Date - 30; 
    //qrJaunumi.SQL.Clear; removed because it would remove the "SELECT ... FROM ..." part 
    qrJaunumi.SQL.Add('WHERE Sanem_datums BETWEEN :StartDate AND :StopDate '); 
    qrJaunumi.Prepared := True; 
    qrJaunumi.ParamByName('StartDate').AsDateTime := d1; 
    qrJaunumi.ParamByName('StopDate').AsDateTime := d2; 
    qrJaunumi.Open; // = qrJaunumi.Active := True; 
end; 

后面的空格“:StopDate”很重要,因为德尔福在参数解析器中的错误,除非他们在新版本中修复它。

+0

Andreas - 您需要删除'qrJaunumi.SQL.Clear;',否则我们将只有一个WHERE子句的查询。 – 2010-04-11 13:50:24

+2

@Gerry是对的,但公平地说,@Andreas编写了你通常期望看到的代码。 OP似乎在其他地方构建查询的第一部分,可能是在设计器(不寒而栗)中。国际海事组织(IMO)将设计时SQL与运行时SQL混合在一起的设计很差。这只是一场等待发生的灾难,而维护将成为一个问题。 – 2010-04-11 14:35:07

+0

+1使用参数。 – 2010-04-11 17:43:42

6

正如robsoft所说,这可能是国际化设置。您可以使用参数化查询 - 如果使用日期和时间,它们通常会更简单。

另外,在开始之后不需要Open - 事实上,它将在没有添加WHERE子句的情况下打开查询。

procedure TfmJaunumi.FormCreate(Sender: TObject); 

var d1, d2: TDate; 

begin d1:= Date; d2:= Date-30; With 
qrJaunumi do 
     begin 
     SQL.Append('WHERE Sanem_datums BETWEEN :StartDate AND :EndDate'); 
     // exact expression will vary according to DB connection type. 
     // Example is for TADOQuery. 
     Parameters.ParamByName('StartDate').Value := d1; 
     Parameters.ParamByName('EndDate').Value := d2; 
     Active := True; 
     end; 
end; 
+0

+1这就是我自己倾向于这种事情的方式。 :-) – robsoft 2010-04-11 14:16:28

+1

+1使用参数。 – 2010-04-11 17:42:36

0

您好我有同样的错误,发现从MS支持不同的解决方案:

SQL.Text:= '删除*从表名,其中((硝酸钾=' +( inttostr(userNo))+')和(Sanem_datums> =#'+(FormatDateTime('mm-dd-yy',d1))+'#))'; ExecSQL;

https://support.microsoft.com/en-us/kb/175258

+0

欢迎来到Stack Overflow。请熟悉如何问一个好问题:)请做一个格式化,并将代码包装在代码部分:)祝你好运:) – DawidPi 2015-10-17 21:42:45

相关问题