2008-11-04 31 views
3

我遇到問題,從我的程序的用戶在運行時定義的查詢中獲取字段列表。我讓我的用戶將一個SQL查詢輸入到一個備忘錄控件中,然後我想讓他們瀏覽將返回的字段,並執行格式化輸出,總計列值等操作。所以,我必須得到列名,以便他們有一個地方可以輸入附加信息。從DBExpress獲取字段列表TSQLQuery

我會做得很好,如果沒有參數,但我也必須讓他們爲查詢定義過濾器參數。所以,如果我想將參數設置爲空,我必須知道參數的數據類型是什麼。

我使用Delphi 2006.我使用DBExpress組件TSQLConnection和TSQLQuery連接到Firebird 2.1數據庫。以前,我成功地使用了:

for i:= 0 to Qry.Params.Count - 1 do Qry.Params [i] .value:= varNull;

我發現我有一個問題,當我試圖使用日期參數。這只是一個巧合,直到那時我的所有參數都是整數(記錄ID)。事實證明varNull只是一個值爲1的枚舉常量,所以我得到了可接受的結果(沒有記錄)工作正常。

我只需要一個字段列表。也許我應該解析SQL語句的SELECT子句。我認爲設置Qry.Prepared到True會給我一個領域的清單,但沒有這樣的運氣。它需要參數的值。

如果你有一個想法,我一定會喜歡聽。謝謝你的幫助。

回答

2

又回答「怎麼我很感興趣。我的方法適用於(與我的查詢),因爲它們已經預先定義了PARAMDS的數據類型預設爲正確的類型:)

我不知道你如何期待查詢知道或派生數據類型因爲你甚至沒有選擇它所針對的領域。

所以我認爲你的查詢設置和用戶輸入法需要更多的關注。我剛纔查了一下我剛纔做了這個。我不使用參數化查詢 - 我只是從用戶那裏獲取「參數值」,並將它們直接放入SQL中。所以,你的SQL行文:

SELECT s.hEmployee,e.sLastName
FROM PR_Paystub小號
INNER JOIN PR_Employee E對e.hKey = s.hEmployee
WHERE s.dtPaydate> 01/01/2008'

因此不需要參數類型知識。並不能阻止用戶進入垃圾,但可以追溯到輸入控制:)

1

我不確定你使用的Delphi版本是什麼。在根據變量類型的德爾福2006年幫助,它說:

特殊的轉換規則適用於System單元聲明的 Borland.Delphi.System.TDateTime類型 。當一個 Borland.Delphi.System.TDateTime是 轉換爲任何其他類型,它 對待作爲一個正常的雙。當 整數,實數或布爾值被轉換爲Borland.Delphi.System.TDateTime, 時,它首先被轉換爲Double, ,然後讀取爲日期時間值。當一個 字符串轉換爲 Borland.Delphi.System.TDateTime時,它被解釋爲使用 區域設置的日期時間值的 。當一個 未分配的值轉換爲 Borland.Delphi.System.TDateTime,它是 對待像真正或整數值 0.將空值轉換爲Borland.Delphi.System.TDateTime引發 例外。

最後一句對我來說似乎很重要。我會讀取varNull無法轉換爲TDateTime以放入該字段,因此您會遇到您遇到的異常。

這也意味着這是唯一的特例。

你不能做這樣的事情:

for i := 0 to Qry.Params.Count - 1 do 
begin 
    if VarType(Qry.Params[i].value) and varTypeMask = varDate then 
    begin 
    Qry.Params[i].value := Now; //or whatever you choose as your default 
    end 
    else 
    begin 
    Qry.Params[i].value := varNull; 
    end; 
end; 
2

雖然略有不同的數據集類型,這是我用的TClientdataSet簡單而有效的:)

for i := 0 to FilterDataSet.Params.Count -1 do 
begin 
Case FilterDataSet.Params.Items[i].Datatype of 
    ftString: 
    ftSmallint, ftInteger, ftWord: 
    ftFloat, ftCurrency, ftBCD: 
    ftDate: 
    ftTime: 
    ftDateTime: 
    . 
    . 
    . 
end; 

結束使用;
你不能做與查詢類似的東西嗎?

2

你們使這種方式太辛苦:

for i := 0 to Qry.Params.Count - 1 do begin 
    Qry.Params[i].Clear; 
    Qry.Params[i].Bound := True; 
end; 
0
TmpQuery.ParamByName('MyDateTimeParam').DataType := ftDate; 
TmpQuery.ParamByName('MyDateTimeParam').Clear; 
TmpQuery.ParamByName('MyDateTimeParam').Bound := True; 
0

我最終什麼事做的是:

sNull := 'NULL'; 
Qry.SQL.Add(sSQL); 
for i := 0 to Qry.Params.Count - 1 do begin 
    sParamName := Qry.Params[i].Name; 
    sSQL := SearchAndReplace (sSQL, ':' + sParamName, sNull, DELIMITERS); 
end; 

我不得不寫SearchAndReplace但是這很簡單。分隔符只是表示單詞結束的字符。