2014-07-19 66 views
0

我試圖過濾delphi上的ado數據庫表。如何使用sql查詢在delphi中的ado數據庫中搜索字段?

我有一個dbgrid連接到查詢(qryData),只要執行此代碼,然後dbgrid變空白,沒有進一步發生。即使我鍵入一個有效的字段名稱,它應該然後顯示它在dbgrid,但它什麼也沒有顯示。我究竟做錯了什麼?

procedure TfrmProjects.cbxColumnsSelect(Sender: TObject); 
begin 
if edtsearch.Text = '' then 
    begin 
     showmessage('The search field should be entered'); 
     exit; 
    end 
else 
    begin 
     ssearch:= edtsearch.Text; 
     showmessage(ssearch); 
    end; 

if cbxColumns.ItemIndex = -1 then 
    begin 
    showmessage('Please select a field'); 
    exit; 
    end 
else 
    begin 
    scolumn:= cbxColumns.Items[cbxColumns.itemindex]; 
    showmessage(scolumn); 
    end; 

with dmUsers do 
begin 
    with qryData do 
    begin 
     sql.Clear; 
     sql.Text := 'Select * FROM tbl_projects where' + quotedstr(scolumn) + ' = ' +quotedstr(ssearch); 
     open; 
    end; 
end; 
+0

對不起我的代碼塊不是很整齊 – user2595912

+0

「過濾器」可能是不適合你想要做什麼是正確的字。只是要清楚:你試圖做的是讓用戶從組合框中選擇用戶希望搜索的關聯表中的列,提示用戶在表列中匹配並執行值一個Sql查詢來查找匹配查詢的錶行? – MartynA

+0

@ user2595912:'... where'+ quotedstr(scolumn)'將成爲'...其中「xyfield」'你可以看到'where'和''xyfield「之間沒有空格! –

回答

1

以下適用於我。您將需要將對qryData的引用更改爲dmUsers.qryData。順便說一句,請儘量避免使用「with ...」

請注意,您構建的SQL並不理想,因爲它不考慮所搜索的列是否爲需要值的數據類型在查詢中指定用引號括起來。列名不需要用引號括起來,但如果它有嵌入空格,則可能需要在它周圍的方括號[]。事實上,你在列名周圍引用了引號是網格變空白的原因 - 你要求服務器上的Sql搜索引擎的所有行都是'one string'='another string',對於任何行都是false所以沒有返回。順便說一句,這是與你有時看到的Sql示例有關,其中有where子句,如'where 1 = 2';當然,這絕對不是真的,並且這個想法是強制搜索引擎解析查詢而不返回任何行。

作爲@ mostkito-x評論說,與您的查詢的原始版本的主要問題之一是查詢的元素之間缺乏空間使用空間寬鬆,所以你可以看到你在做什麼。如果您在查詢時遇到問題,沒有什麼不好的地方可以將它的文本放入您的表單中的備忘錄(設置爲像Courier這樣的固定字體),這樣您就可以看到您是否構建了您認爲自己的查詢。

順便說一句,如果你沒有收集,使用QuotedStr圍繞搜索值的字符串數據類型的優點是正確處理搜索值有嵌入式報價(如o'Reilly)的情況。

procedure TForm1.CbxColumnNameClick(Sender: TObject); 
// NOTE: The following code assumes that either qryData is open when it is called 
//  or has persistent TFields defined 
var 
    FieldName, 
    ValueToSearch, 
    Sql : String; 
    UseQuotedValue : Boolean; 
begin 
    FieldName := cbxColumnName.Text; 
    if FieldName = '' then begin 
    ShowMessage('No field selected for search.'); 
    Exit; 
    end; 

    UseQuotedValue := qryData.FieldByName(FieldName).DataType in [ftString, ftWideString, ftMemo]; 

    ValueToSearch := edtSearch.Text; 
    if UseQuotedValue then 
    ValueToSearch := QuotedStr(ValueToSearch); 

    Sql := 'select * from tblProjects where ' + FieldName + ' = ' + ValueToSearch; 

    if qryData.Active then 
    qryData.Close; 
    qryData.SQL.Text := Sql; 
    qryData.Open; 
end; 
這種類型的查詢

還閱讀了關於「SQL注入」惡意軟件風險(http://en.wikipedia.org/wiki/Sql_injection)。收到的智慧是,降低風險的措施是使用參數化查詢。不幸的是,對於您的任務,雖然您可以指定要匹配的列值作爲參數,但您無法在ADO中參數化名稱爲的列

要使用參數化查詢時,SQL將目光從tblProjects像

選擇*其中SomeColumn =:someValue中

然後,在IDE Object Inspector中你需要定義qryData參數並且在執行查詢之前,請執行qryData.Parameters.ParamByName('somevalue')。Value:= edtSe​​arch.Text。但是,正如我所說的,您無法參數化列名進行搜索。

+0

+1你說的很好:'試着避免使用...'。您還應該提到,查詢通常是由於指令之間的空間不足而導致的。如果你看看完成的'sqlquery',大部分都是錯誤的。 –

+0

@moskitox,是的好點,我馬上更新我的答案。 – MartynA

+1

請調整您的示例並顯示參數的使用情況,否則不會+1;) – whosrdaddy

0

從我所看到的問題是在這條線:

sql.Text := 'Select * FROM tbl_projects where' + quotedstr(scolumn) + ' = ' +quotedstr(ssearch); 

它應該是:

sql.Text := 'Select * FROM tbl_projects where ' + scolumn + ' = ' +quotedstr(ssearch); 

第一QuotedStr引用的列名與普通單引號,這將compate 2字符串值 - 一個等於列的名稱,另一個等於搜索字符串。

如果在列名中使用空格,則應該用適當的字符括起來。例如,在MySQL中,你應該使用:

sql.Text := 'Select * FROM tbl_projects where `' + scolumn + '` = ' +quotedstr(ssearch); 
相關問題