全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:5588
推到 Plurk!
推到 Facebook!

如何組合SQL + parameters成完整SQL呢?

答題得分者是:sryang
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-05-31 15:47:35 IP:59.120.xxx.xxx 訂閱
因為擔心可能會有SQL Injection問題,所以才想用TParameters做參數化查詢

但爬文後發現似乎沒有人問過,也不知道是不是問錯問題

總之大致上像是以下內容

[code delphi]
ADOQuery1.Close;
ADOQuery1.SQL.Text:='select * from Temp_Table where id = :id and Name = :nm ';
ADOQuery1.Parameters.ParamByName('id').Value := 1;
ADOQuery1.Parameters.ParamByName('nm').Value := 'Fs';
ADOQuery1.Open;
Memo1.Line.Add(ADOQuery1.SQL.Text);
[/code]

得到的結果仍然是未組譯的SQL……
不知道有什麼方式可以組成功呢?
編輯記錄
GrandRURU 重新編輯於 2011-05-31 01:48:06, 註解 無‧
老大仔
尊榮會員


發表:78
回覆:837
積分:1088
註冊:2006-07-06

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-05-31 17:44:55 IP:59.120.xxx.xxx 未訂閱
GrandRURU 大大:
為何不再用另一個String來做暫存SQL指令呢???

Ex:
var
s: String;
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text:='select * from Temp_Table where id = :id and Name = :nm ';
ADOQuery1.Parameters.ParamByName('id').Value := 1;
ADOQuery1.Parameters.ParamByName('nm').Value := 'Fs';
s := 'select * from Temp_Table where id = ''' IntToStr(1) ''' ' and Name = ''FS''';
ADOQuery1.Open;
.....
end;

小弟還是個小小新手
才疏學淺
不知道這樣O不OK>"<


===================引 用 GrandRURU 文 章===================
因為擔心可能會有SQL Injection問題,所以才想用TParameters做參數化查詢

但爬文後發現似乎沒有人問過,也不知道是不是問錯問題

總之大致上像是以下內容

[code delphi]
ADOQuery1.Close;
ADOQuery1.SQL.Text:='select * fromTemp_Table where id = :id and Name = :nm ';
ADOQuery1.Parameters.ParamByName('id').Value := 1;
ADOQuery1.Parameters.ParamByName('nm').Value := 'Fs';
ADOQuery1.Open;
Memo1.Line.Add(ADOQuery1.SQL.Text);
[/code]

得到的結果仍然是未組譯的SQL……
不知道有什麼方式可以組成功呢?
cancer
高階會員


發表:58
回覆:319
積分:190
註冊:2004-07-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-05-31 18:58:17 IP:220.128.xxx.xxx 未訂閱
請問,您是用 Delphi 寫網頁程式嗎?一般桌上 Application 程式沒有 Sql Injection 的問題。
===================引 用 GrandRURU 文 章===================
因為擔心可能會有SQL Injection問題,所以才想用TParameters做參數化查詢

但爬文後發現似乎沒有人問過,也不知道是不是問錯問題

得到的結果仍然是未組譯的SQL……
不知道有什麼方式可以組成功呢?
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2011-06-01 08:22:02 IP:59.120.xxx.xxx 訂閱
 to 老大仔大大
這方式目前我看是有個問題,就是param屬性很難判斷是int還是str格式
但整體來說這個方式不錯,我會嚐試看看的

to cancer大大
並非是使用delphi寫網頁程式,但真的沒有 sql injection的問題?
不知這個理論可以在哪邊可以得到相關資訊呢?

cancer
高階會員


發表:58
回覆:319
積分:190
註冊:2004-07-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2011-06-01 11:34:02 IP:220.128.xxx.xxx 未訂閱
Delphi 資料庫程式幾乎都用 DataSet 來操作,不使用 Sql 指令,不會有 sql injection 的問題。
查詢界面是唯一有可能 Inject 的地方,但幾乎都用 T..DataSet(沒事不要用 T..Query),T..DataSet 不能下 insert,update,drop 之類的。
程式中會夾雜 T...Query 之類的元件來做 Insert, update..等等,使用者很難在界面元件影響 Sql 指令的寫法,唯一進入點是 TDBEdit, TMemo 之類的,機會極微,再說,程式是給員工或會員用的,要經過登入過程,一般的這種程式,都會記下登入者是誰,在甚麼時候登入,每筆資料都有異動人員和異動時間,自家員工敢用 Sql Injection 的話,早晚也查得出來。
所以,放心吧。
===================引 用 GrandRURU 文 章===================
to cancer大大
並非是使用delphi寫網頁程式,但真的沒有 sql injection的問題?
不知這個理論可以在哪邊可以得到相關資訊呢?

aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2011-06-01 11:46:20 IP:210.64.xxx.xxx 訂閱
使用parameters的方式,其實delphi最後是把整個語句轉成類似下面的樣子,餵給sql sever

exec sp_executesql N'select * from Customers where CustomerID = @P1', N'@P1 sql_variant', N'AROUT'

所以你沒法得到你想要的樣子!

至於sql injection 是一種技術,比如畫面要你輸入名字的地方,有心人士反而輸入sql的句字進去,然後該值經你的字串相加後,變成惡意的程式,然後導致被獲取一個最高權限或是寫入木馬等等,進一步為了把你的伺服器變成zombie,從此被控制著。

由上面的簡單說明可知,一般是網頁的型態比較會引起興趣而被攻擊。如果是一般的軟體,是很少人會想要幹這樣的事,因為該軟體多數就是安裝在「自己」的電腦上,因此比較沒有什麼為了得到權限,或是要植入木馬的情形 (如果要的話,就直接下毒就好)

不過,良好的習慣應該沒有損失才是。不過見仁見智就是了!

===================引 用 GrandRURU 文 章===================
to 老大仔大大
這方式目前我看是有個問題,就是param屬性很難判斷是int還是str格式
但整體來說這個方式不錯,我會嚐試看看的

to cancer大大
並非是使用delphi寫網頁程式,但真的沒有 sql injection的問題?
不知這個理論可以在哪邊可以得到相關資訊呢?

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#7 引用回覆 回覆 發表時間:2011-06-01 18:22:20 IP:114.35.xxx.xxx 訂閱
  1. 姑且不論桌面應用軟體被 SQL Injection 的可能性高低,
    使用參數化查詢可以輸入「單引號」,而不需額外的檢查跟處理,光是這一點,就值得使用
  2. Param 有 DataType 屬性可以知道型態。基本上,數值型態 (ftSmallint、ftInteger、ftWord、ftFloat、ftCurrency、ftBCD、ftLargeint、ftFMTBcd)
    不須 quoted,其他型態則要
  3. Param 可以使用參數的真實型態作為其值,不須餵給字串,然後由 database server 再轉換一次,尤其是日期型態的查詢條件最為明顯
    SQL Server:DateField = '2011-06-01'
    Oracle: DateField = to_date('2011-06-01','yyyy-mm-dd')
    Access:DateField = #2011-06-01#
    以上的語法差異若使用參數化查詢,一律可以使用 DateField = :DateField
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#8 引用回覆 回覆 發表時間:2011-06-02 07:48:17 IP:114.35.xxx.xxx 訂閱
針對樓主的問題,我的處理方式是這樣的:
[code delphi]
// 依照參數型態,取得參數的字串值
function TForm1.GetParamValue(Value: Variant; DataType: TDataType): string;
begin
// 數值型態,不要 ''
if DataType in [ftSmallint, ftInteger, ftWord, ftFloat, ftCurrency, ftBCD, ftLargeint, ftFMTBcd] then
Result := VarToStr(Value)
// 日期型態,要先轉為 TDateTime 再 FormatDateTime
else if DataType in [ftDate, ftTime, ftDateTime, ftTimeStamp] then
Result := QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss', VarToDateTime(Value)))
// 其他都當成字串,要 ''
else
Result := QuotedStr(VarToStr(Value));
end;

// 將參數換成對應的字串值,給 TADODataSet 用的
function TForm1.FillInParam(SQL: string; Params: TParameters): string;
var i: integer;
sValue: string;
begin
Result := SQL;

for i := 0 to Params.Count - 1 do
begin
sValue := GetParamValue(Params[i].Value, Params[i].DataType);
Result := StringReplace(Result, ':' Params[i].Name, sValue,
[rfReplaceAll, rfIgnoreCase]);
end;
end;

// 將參數換成對應的字串值,給 TADODataSet 以外的資料集元件用的
function TForm1.FillInParam(SQL: string; Params: TParams): string;
var i: integer;
sValue: string;
begin
Result := SQL;

for i := 0 to Params.Count - 1 do
begin
sValue := GetParamValue(Params[i].Value, Params[i].DataType);
Result := StringReplace(Result, ':' Params[i].Name, sValue,
[rfReplaceAll, rfIgnoreCase]);
end;
end;
[/code]

------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
GrandRURU
站務副站長


發表:240
回覆:1680
積分:1874
註冊:2005-06-21

發送簡訊給我
#9 引用回覆 回覆 發表時間:2012-02-21 09:49:20 IP:59.120.xxx.xxx 訂閱
遇到這種的…我看也只能認了



[資料來源]千万别惹程序员
===================引 用 aftcast 文 章===================
使用parameters的方式,其實delphi最後是把整個語句轉成類似下面的樣子,餵給sql sever

exec sp_executesql N'select * from Customers where CustomerID = @P1', N'@P1 sql_variant', N'AROUT'

所以你沒法得到你想要的樣子!

至於sql injection 是一種技術,比如畫面要你輸入名字的地方,有心人士反而輸入sql的句字進去,然後該值經你的字串相加後,變成惡意的程式,然後導致被獲取一個最高權限或是寫入木馬等等,進一步為了把你的伺服器變成zombie,從此被控制著。

由上面的簡單說明可知,一般是網頁的型態比較會引起興趣而被攻擊。如果是一般的軟體,是很少人會想要幹這樣的事,因為該軟體多數就是安裝在「自己」的電腦上,因此比較沒有什麼為了得到權限,或是要植入木馬的情形 (如果要的話,就直接下毒就好)

不過,良好的習慣應該沒有損失才是。不過見仁見智就是了!
系統時間:2024-04-26 6:58:37
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!