2010-04-11 16 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

相關問題