SQL語法內含雙引號新增問題 |
答題得分者是:TWY
|
lamp
一般會員 發表:3 回覆:10 積分:7 註冊:2006-07-13 發送簡訊給我 |
測試環境 MSSQL 2000 D5 主要問題是SQL語法內含 " 時要新增至資料庫發生錯誤. 我的寫法在如下. sSQL:=' insert into test_P ' ' (pnumber,pname) ' ' values ' ' (' ' ''' Edit1.Text ''',' ' ''' Edit2.Text '''' ')'; 利用ADO新增及ClientDataSet1新增會有不同的結果. ADO新增 OK, ClientDataSet1新增會有錯誤產生. 我想請教一下我的寫法是有什麼地方出錯了. 感謝. PS:附檔含測試程式及TEST TABLE 資料結構 編輯記錄
lamp 重新編輯於 2009-11-18 11:48:45, 註解 無‧
|
holydisciple
一般會員 發表:3 回覆:24 積分:10 註冊:2009-11-06 發送簡訊給我 |
你好,
通常我都不直接用 Insert,而是用 DataSet 先讀取零筆進來,如下 ds.close; ds.CommandText := 'select top 0 * from 資料表名稱'; ds.Open; ds.Append; // 填資料 ds.Post; 這樣就不用管那些單引號了,但如果要用 Insert,一定要先 StringReplace,因為內容是使用者輸入的,你不能禁止他不能輸入單引號,例如 var s1, s2 : string; s1 := StringReplace(Edit1.Text, '''', '', [rfReplaceAll]); s2 := StringReplace(Edit2.Text, '''', '', [rfReplaceAll]); sSQL := Format('insert into test_P (pnumger, pname) values(''%s'', ''%s'')', [s1, s2]); // 用 Format() 才不會打那麼多單引號
------
有沒有可能,上帝使用程式操作世界? |
lamp
一般會員 發表:3 回覆:10 積分:7 註冊:2006-07-13 發送簡訊給我 |
===================引 用 holydisciple 文 章=================== 你好, 通常我都不直接用 Insert,而是用 DataSet 先讀取零筆進來,如下 ds.close; ds.CommandText := 'select top 0 *from 資料表名稱'; ds.Open; ds.Append; // 填資料 ds.Post; 這樣就不用管那些單引號了,但如果要用 Insert,一定要先 StringReplace,因為內容是使用者輸入的,你不能禁止他不能輸入單引號,例如 var s1, s2 : string; s1 := StringReplace(Edit1.Text, '''', '', [rfReplaceAll]); s2 := StringReplace(Edit2.Text, '''', '', [rfReplaceAll]); sSQL := Format('insert into test_P (pnumger, pname) values(''%s'', ''%s'')', [s1, s2]); // 用 Format() 才不會打那麼多單引號 感謝您的回覆... 1.大大所提供的方法是第一種方案是可以解決沒錯,但是因為要維護舊系統修改幅度過大,可能無法依法執行. 2.小弟目前的問題是輸入雙引號 < " >的問題並不是單引號的問題.舉例來說以下這段SQL語法,利用TADOQuery元件來新增不會有任何錯誤產,但是利用TClientDataSet 郤會產生錯誤無法新增. insert into test_P (pnumber,pname) values ( 'P0004', '鋼管 1"') PS:我提供的測試檔有簡單的程式,有興趣的朋友可以試試看. |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
|
lamp
一般會員 發表:3 回覆:10 積分:7 註冊:2006-07-13 發送簡訊給我 |
===================引 用 TWY 文 章=================== 你好。試著用QuotedStr() 包起參數,應該可以解決你的問題。(說明請按F1) 感謝您的回覆...測試結果TClientDataSet還是不行. 原本的sql語法如下 sSQL = insert into test_P (pnumber,pname) values ( 'P0006', '鋼管 1"' ) 加入QuotedStr() , sSQL:=QuotedStr(sSQL) 後 sSQL= ' insert into test_P (pnumber,pname) values ( ''P0006'', ''鋼管 1"'' )' 執行結果還是產生錯誤. 利用 TADOQuery 加入QuotedStr() 原本的sql語法如下 sSQL = insert into test_P (pnumber,pname) values ( 'P0006', '鋼管 1"' ) 加入QuotedStr() , sSQL:=QuotedStr(sSQL) 後 sSQL= ' insert into test_P (pnumber,pname) values ( ''P0006'', ''鋼管 1"'' )' 執行完,可以順利新增. 以TADOQuery來看,不管是insert into test_P (pnumber,pname) values ( 'P0006', '鋼管 1"' ) 或 ' insert into test_P (pnumber,pname) values ( ''P0006'', ''鋼管 1"'' )' , 該元件執行時都能順利解析SQL語法. 是不是 ClientDataSet 還有一些參數可以調整,還是BDE的問題? |
ko
資深會員 發表:28 回覆:785 積分:444 註冊:2002-08-14 發送簡訊給我 |
請問
insert into test_P (pnumber,pname) values ( 'P0006', '鋼管 1"' ) 這一句您測試過在 Analyzer 中執行過嘛? 還有QuotedStr() 的意思是..包在EDIT1... sSQL:=' insert into test_P ' ' (pnumber,pname) ' ' values ' ' (' ' QuotedStr(Edit1.Text) ',' ' 'QuotedStr(Edit2.Text) QuotedStr('"') ')';
------
====================== 昏睡~ 不昏睡~ 不由昏睡~
編輯記錄
ko 重新編輯於 2009-11-17 14:09:50, 註解 無‧
|
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
抱歉先前給了錯誤方向,QuotedStr一般用來解決內容有單引號的問題,雙引號對在Delphi的SQL來說不具有破壞力(不會有問題)。
也謝謝 ko 兄幫忙舉例了 QuotedStr 的用法(只需要包起參數/變數,不是把整個 SQL 字串包起來喔) 我下載了你的範例也建立起 test_p 來測試,我敢說你的問題不是 SQL 語法問題,我有用你的範例新增過了... 因為我沒有另外在寫個 AP Server,所以直接在你傳上的程式拉個 TDabase TQuery TDataSetProvider 元件來連結資料庫(跟實際連結AP Server意思一樣),沒有改你的任何程式按下 Button1 (OnClick) => 新增成功! 其中屬性比較特別的就是 TDataSetProvider.Options.poAllowCommandText 必須設定 True ,這樣才能讓 TClientDataSet 自己傳上 SQL 來執行,我猜你應該是這裡沒設吧!?(或其他 NTier 連結上的問題,因為你忘了把錯誤訊息 Post 出來,所以僅能做此猜測) |
lamp
一般會員 發表:3 回覆:10 積分:7 註冊:2006-07-13 發送簡訊給我 |
===================引 用 TWY 文 章===================
抱歉先前給了錯誤方向,QuotedStr一般用來解決內容有單引號的問題,雙引號對在Delphi的SQL來說不具有破壞力(不會有問題)。 也謝謝 ko 兄幫忙舉例了 QuotedStr 的用法(只需要包起參數/變數,不是把整個 SQL 字串包起來喔) 我下載了你的範例也建立起 test_p 來測試,我敢說你的問題不是 SQL 語法問題,我有用你的範例新增過了... 因為我沒有另外在寫個 AP Server,所以直接在你傳上的程式拉個 TDabase TQuery TDataSetProvider 元件來連結資料庫(跟實際連結AP Server意思一樣),沒有改你的任何程式按下 Button1 (OnClick) => 新增成功! 其中屬性比較特別的就是 TDataSetProvider.Options.poAllowCommandText 必須設定 True ,這樣才能讓 TClientDataSet 自己傳上 SQL 來執行,我猜你應該是這裡沒設吧!?(或其他 NTier 連結上的問題,因為你忘了把錯誤訊息 Post 出來,所以僅能做此猜測) ======= 感謝,ko兄及TWY大大的回覆. 抱歉,誠如TWY大大所言,我的測試程式有點問題並不是SQL 語法問題, sSQL = insert into test_P (pnumber,pname) values ( 'P0006', '鋼管 1"' ) ,確定是可以新增的. 我的測試程式無法新增是因為我只設ClientDataSet1我只設定了RemoteServer,忘了設定ProviderName. 造成了資料無法新增. 我的測試程式稍為改了一下,我將我無法順利新增的sql語法我重po如下. insert into REQUIRE ( RENUMBER,SERIAL,PNUMBER,PNAME, LISTPRICE,QUODISCOUNT,QUODISPRICE,AMOUNT, LTCOST,EQUCOST,REMARK,CTDT,CTRU,CHECKED, SWTYPE,SWNUMBER ) VALUES ('200911170002','1','IPF6445110','SGP6445 白碳鋼鋼管 6.1M 1"','394','100','394','3','1182','393.979',' ','2009/11/17 16:56','0001','0','','') 以上語法,我利用Analyzer執行時可以順利新增資料.但是我利用我的測試程式去執行時會發生 Missing right quote 的錯誤訊息. 麻煩那位大大有空幫我看一下我的語法是那出錯了.感謝! PS:測試檔已更新,麻煩重新下庫內含 CREATE REQUIRE table 的語法. |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
我剛玩了很久,這的確是個有趣的現象,我在想...是否為元件的 Bug 呢!?
(雖然我盡可能要求自己不要把不能說明或理解的現象歸納為元件Bug,不過這個現象倒真的超出我的認知了) 我把重現的規則簡單描述出來,讓有能力的高手來試玩、或給大家解惑一下~ 建立一個簡單 Table 只要三個欄位,假設 FInt,FString,FDateTime 若 SQL 為 insert into ATable(FString,FDateTime) values('A"','2009-11-11 12:34:56') 若用 TQuery 直接寫入會得到 "Missing right quote." 的錯誤。若使用 TADOQuery 寫入會得到 "提供不一致或不完全的資訊導致參數物件不適當地被拒。" 的錯誤。用 SQL Monitor 檢視會發現 SQL 變成 insert into REQUIRE ( PNAME,ctdt) VALUES ('A"','2009-11-11 12? 但直接用 SQL Query Analyzer 新增是 OK的。 另外,若語法把"字串"、"日期"欄位隔開,就不會有錯誤,例如 insert into ATable(FString,FInt,FDateTime) values('A"',1,'2009-11-11 12:34:56') 目前看來 SQL 語法字串緊跟著日期欄位時,會把字串內容中的雙引號也當作單引號處理。 這還真的很奇怪哩~ ps: 1.此問題與 NTier or ClientDataSet 無關,直接拉個 DataBase & Query 就可以模擬 2. 我是用 Memo 來輸入 SQL,非寫在 Code 裡,再以 Query.SQL.Text := Memo1.Lines.Text; 方式讀入執行
編輯記錄
TWY 重新編輯於 2009-11-19 11:39:37, 註解 無‧
|
jackiemi2_seed
中階會員 發表:37 回覆:97 積分:76 註冊:2006-09-11 發送簡訊給我 |
我的筆記,QuotedStr是這樣用的,我是用adocom去執行,
clientdataset下sql不會用,參考看看 s:='update test1 '; s:=s 'set ' format('t2=%s',[QuotedStr(edit1.Text)] ) ' '; s:=s 'where t1=''001'' '; adocom.CommandText:=s;
------
OS : Win 7 pro Program : Delphi 7 DataBase : Ms Sql 2008 |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
我想這個問題(現象)已經不是 QuotedStr 能解決的,也與 BDE or ADO,Client-Server or NTier 沒有直接關係了。
有興趣的話,可參照我上面描述簡單方法 try 一下喔~ ===================引 用 jackiemi2_seed 文 章=================== 我的筆記,QuotedStr是這樣用的,我是用adocom去執行, clientdataset下sql不會用,參考看看 s:='update test1 '; s:=s 'set ' format('t2=%s',[QuotedStr(edit1.Text)] ) ' '; s:=s 'where t1=''001'' '; adocom.CommandText:=s; |
jackiemi2_seed
中階會員 發表:37 回覆:97 積分:76 註冊:2006-09-11 發送簡訊給我 |
感覺問題出在,文字有雙引號和datetime同時出現
改用Parameters的方式就可以了,參考看看 ClientDataSet1不知是否有Parameters可以用 s:='insert into ATable(FString,FInt,FDateTime) values(:FString,:FInt,:FDateTime)'; adocom.CommandText:=s; adocom.Parameters.ParamValues['FString']:='A"'; adocom.Parameters.ParamValues['FInt']:=2; adocom.Parameters.ParamValues['FDateTime']:='2009-01-01 1:22:33'; adocom.Execute; 但Parameters在輸入中文字時,好像很容易出問題
------
OS : Win 7 pro Program : Delphi 7 DataBase : Ms Sql 2008 |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
我剛用了一樣的模擬方法(參考上面描述)做了些實驗,這次資料庫換成Oracle 9i,結果如下...
1. BDE 仍然有同樣問題 2. RemObject Data Abstract 套件 OK 3. Oracle Access(ODAC) 套件 OK (後面兩個都是第三方元件) 網路搜尋一下,也有人反應一樣的問題,也有很多解決方法建議 (例如用 StringReplace 等),但就是沒有看到有人對此現象做出原因說明。 目前線索看來,似乎指向這是 Delphi 內部元件的 Bug,除此之外我尚不知道能如何解釋了...
編輯記錄
TWY 重新編輯於 2009-11-22 00:18:11, 註解 無‧
|
lamp
一般會員 發表:3 回覆:10 積分:7 註冊:2006-07-13 發送簡訊給我 |
感謝各位大大的回覆,尤其是TWY大大不辭辛勞的測試.發現不是SQL語法的問題,而是日期欄位出了狀況.
問題我已解決,直接利用SQL函數代入該欄位,確定可以新增. 以下是我的解決方法.大家以後再遇到類似問題可以試.SQL函數各家資料庫略有不同,請自行調整. 原SQL語法: insert into REQUIRE ( RENUMBER,SERIAL,PNUMBER,PNAME, LISTPRICE,QUODISCOUNT,QUODISPRICE,AMOUNT, LTCOST,EQUCOST,REMARK,CTDT,CTRU,CHECKED, SWTYPE,SWNUMBER ) VALUES ('200911170002','1','IPF6445110','SGP6445 白碳鋼鋼管 6.1M 1"','394','100','394','3','1182','393.979',' ', '2009/11/17 16:56','0001','0','','') 新SQL語法: insert into REQUIRE ( RENUMBER,SERIAL,PNUMBER,PNAME, LISTPRICE,QUODISCOUNT,QUODISPRICE,AMOUNT, LTCOST,EQUCOST,REMARK,CTDT,CTRU,CHECKED, SWTYPE,SWNUMBER ) VALUES ('200911170002','1','IPF6445110','SGP6445 白碳鋼鋼管 6.1M 1"','394','100','394','3','1182','393.979',' ', convert(varchar(16),getdate(),120),'0001','0','','')
編輯記錄
lamp 重新編輯於 2009-11-30 11:35:35, 註解 無‧
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |