2011-06-05 94 views
2

而我正在撕裂我的頭髮!AdoQuery不適用於SHOW:命令

即使是一些簡單的像這樣的工作:

procedure MyAdoQueryTest(); 
    const MYSQL_CONNECT_STRING='Driver={MySQL ODBC 5.1 Driver};Server=%s;Port=3306;Database=%s;User=%s;Password=%s;Option=3;'; 

    var AdoConnection : TADOConnection; 
     ADOQuery : TADOQuery; 
     Param : TParameter; 
begin 
    AdoConnection := TADOConnection.Create(Nil); 
    AdoConnection.ConnectionString := Format(MYSQL_CONNECT_STRING,['localhost', 
                    'mysql', 
                   'root', 
                   '']); 
    AdoConnection.LoginPrompt := False; 
    AdoConnection.Connected := True; 

    ADOQuery := TADOQuery.Create(Nil); 
    ADOQuery.Connection := AdoConnection; 
    ADOQuery.Sql.Clear(); 
    ADOQuery.SQl.Add('SHOW :what_to_show'); 

    Param := ADOQuery.Parameters.ParamByName('what_to_show'); 
    Param.DataType := ftString; 
    Param.Value := 'databases'; 

    ADOQuery.Prepared := true; 
    ADOQuery.Active := True; 
end; 

(順便說一句,我真的需要使用「帕拉姆」變量和3陳述,或可我只是`ADOQuery.Parameters.ParamByName(「what_to_show」 ).Value:='databases';?)

無論如何,當我運行它時,我在ADOQuery.SQl.Add('SHOW :what_to_show');處得到一個異常,它說:「參數的類型錯誤,超出了可接受的範圍或與一個另一個」。

我想要做的是做2箇中心函數:一個接受並執行任何不會返回任何數據(比如INSERT INTO)的SQL語句和將會返回的數據(比如SELECT)。

我目前只有這些工作與AdoConnection,但我現在試圖使用AdoQuery,因爲我想參數化我的SQL語句來處理帶有引號的字符串。

我可以halpz?

+0

只是一個猜測,但我認爲AdoQuery是爲那些只有標準的SQL語句,如INSERT,SELECT和DELETE。您可能希望在使用SHOW解決這些問題之前嘗試這些方法,對此,您可能會陷入AdoConnection ...與三條語句相關:您應該可以執行您想要的操作,但您可能需要移動AdoQuery.Prepared之前設置參數值。 – 2011-06-05 06:51:01

+0

@Marjan,對不起,你已經離開了,Params只能用於值,而不能用於其他SQL元素。這是一個普遍的事情。 – Johan 2011-06-05 10:40:12

+0

@johan,我想你誤解了我的陳述。我的意思是你可以做'ADOQuery.Parameters.ParamByName('what_to_show')。value:='databases';'參數。我沒有說你可以使用參數來支持SHOW。 – 2011-06-05 13:01:54

回答

5

的錯誤是在這裏:

ADOQuery.SQl.Add('SHOW :what_to_show'); 

:Param只能用於數值,而不是動態列/關鍵字/表/數據庫名。
這是因爲如果它像那樣工作,則根據參數內容的不同,會有SQL注入風險。

爲了解決這個問題,您必須將您的what_to_show thingy注入到SQL字符串中。

像這樣:

var 
    what_to_show: string; 
begin 
    .... 
    what_to_show:= 'tables'; 
    ADOQuery.SQL.Text:= ('SHOW '+what_to_show); 
    .... 

現在,它會工作。

enter image description here警告
讓你注入SQL以防止用戶能夠注入他們的SQL代碼到查詢確認測試的一切。
參數可防止SQL注入,但由於您無法在此處使用它們,因此您需要根據預先批准的值列表對其進行檢查。例如一個stringlist持有所有允許的what_to_shows。
轉義或使用特殊字符是沒用的。

安全注射的示例代碼

var 
    what_to_show: string; 
    i: integer; 
    inputapproved: boolean; 
begin 
    .... 
    what_to_show:= lower(trim(someinput)); 
    i:= 0; 
    inputapproved:= false; 
    while (i < WhiteList.count) and not(inputapproved) do begin 
    inputapproved:= (what_to_show = lower(Whitelist[i])); 
    Inc(i); 
    end; {while} 
    if inputapproved then ADOQuery.SQL.Text:= ('SHOW '+what_to_show); 
    .... 
相關問題