<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      歡迎大家下載試用折桂單點登錄系統(tǒng), https://www.zheguisoft.com

      評“CPQuery, 解決拼接SQL的新方法”

      最近看到一篇“CPQuery, 解決拼接SQL的新方法”(http://www.rzrgm.cn/fish-li/archive/2012/09/10/CPQuery.html),由于里面的思路基本是錯誤的,很擔(dān)心影響園里的初學(xué)者。我在帖子里回復(fù)了幾次,給博主 fish-li 一點小小的建議,沒有想到,這位老兄說不過,就直接刪除我的回帖,包含別人在貼中對我的發(fā)問,如此惡劣行徑,實屬罕見。鄙人不才,不能保證每次發(fā)帖回帖都正確,也有在園中說錯話道歉的時候,但從不刪說錯的、道歉的貼/回復(fù)。

      特另單寫一篇博文,闡述我的觀點,也歡迎大家用踴躍討論。

       

      就事論事,這篇博文的錯誤有以下幾點:

      1. 該 CPQuery 嘗試繞開 Ado.net 的 command.Parameters.Add() ,另寫函數(shù)來對付 SQL 注入。這是很錯誤的做法。

      很多人都以為,對付SQL 注入很容易,只要把單引號處理掉就行了,容易。其實,這種想法是非常錯誤的。

      對于類似這樣的代碼:

      query = query + " and ProductName like '" + p.ProductName + "'";

       

      轉(zhuǎn)換字符數(shù)據(jù)中間的特殊字符,實際上是一件相當(dāng)困難的事情。PHP 中有個 addslashes 函數(shù),發(fā)布多年,漏洞不斷,補丁也不斷:

      Addslashes() 漏洞(2004年,%00)

      http://www.ugia.cn/?p=23

       

       

      addslashes:會導(dǎo)致SQL注入漏洞(2006年,0xbf27)
      http://blog.csdn.net/felio/article/details/1226569

       

      GBK字符集下addslashes函數(shù)的注入漏洞及BUG的解決辦法(2011 年,addslashes函數(shù)在進行轉(zhuǎn)義的時候,只對二進制字符串操作二不考慮字符集)

      http://www.itlearner.com/article/4824

       

       

      從上面可以從側(cè)面看出其中的難度。

       

      在 SQL 注入(http://msdn.microsoft.com/zh-cn/library/ms161953.aspx) 這篇文章中,提到:

      如果可能,拒絕包含以下字符的輸入:

      輸入字符

      在 Transact-SQL 中的含義

      ;

      查詢分隔符。

      '

      字符數(shù)據(jù)字符串分隔符。

      --

      注釋分隔符。

      /* ... */

      注釋分隔符。服務(wù)器不對 /* 和 */ 之間的注釋進行處理。

      xp_

      用于目錄擴展存儲過程的名稱的開頭,如 xp_cmdshell。

       

      然而,這僅僅是 SQL Server 所需要處理的特殊字符,如果是其他數(shù)據(jù)庫,又有別的字符需要處理,難度不是一點點。

      如果用 Ado.net ,它所帶的驅(qū)動程序,已經(jīng)替我們做了這些事情,我們只需要調(diào)用 cmd.Parameters.Add(p); 即可。

        

       

      當(dāng)然了,這篇微軟的文章,還提到,"應(yīng)檢查所有調(diào)用 EXECUTE、EXEC 或 sp_executesql 的代碼 ...在選擇的每個存儲過程中,驗證是否對動態(tài) Transact-SQL 中使用的所有變量都進行了正確處理..."。這個難度就大了。存儲過程中,難以調(diào)用 cmd.Parameters.Add(p) 來轉(zhuǎn)換參數(shù)??磥碓诖鎯^程中,處理字符串起來,要格外小心。

       

      嘗試自己寫 SQL 特殊字符處理函數(shù),是一個特別沒有“投資收益比”的事情,很難寫好,就算寫好了,也沒有什么特別的收益,因為數(shù)據(jù)庫的驅(qū)動程序,已經(jīng)把這個做好了。無論是 C# 還是 Java 的程序員,都不應(yīng)自己寫 addslashes 函數(shù)。

       

      在 Java 中,Apache 有個 http://commons.apache.org/lang/ ,本來提供了一個 StringEscapeUtils.escapeSql() 函數(shù),但是后來主動去掉了這個函數(shù),理由是:

      StringEscapeUtils.escapeSql has been removed from the API as it was misleading developers to not use PreparedStatement

       

      也就是說,這類 escapeSql() 函數(shù),誤導(dǎo)開發(fā)者不用開發(fā)語言本身的 PreparedStatement,是不好的。所以,最好不要寫此類函數(shù)。

       

      2. CPQuery 的另一個,據(jù)博主 fish-li 所說,“優(yōu)點”之一,就是拼接 SQL 方便。然而,使用 cmd.Parameters.Add(p) 一樣拼接 SQL 方便:

      using (DbCommand cmd = this.mCon.CreateCommand()) 
      { 
          cmd.Transaction = this.mTrans; 
      
          string sql = "select ...  from ... where 1=1 and ... "; 
      
          if (uploadFlag != null) 
          { 
              sql += " and t." + TtDataVeccTransferBaseDao.COL_UPLOADFLAG + "= ?"; 
      
              DbParameter p = cmd.CreateParameter(); 
              p.ParameterName = "@COL_UPLOADFLAG"; 
              p.Value = uploadFlag; 
              cmd.Parameters.Add(p); 
          } 
          ...
      }

       

       以下幾行,可以寫在一個公共函數(shù)中: 

      DbParameter p = cmd.CreateParameter(); 
      p.ParameterName = "@COL_UPLOADFLAG"; 
      p.Value = uploadFlag; 
      cmd.Parameters.Add(p); 

       


      這樣最后變成只有兩行: 

       

      sql += " and t." + TtDataVeccTransferBaseDao.COL_UPLOADFLAG + "= ?"; 
      addParameterValue(cmd,uploadFlag); 

       

      從這兩方面看來,CPQuery 本身出現(xiàn)的意義就有疑問。

       

      一般來說,另寫數(shù)據(jù)庫訪問組件/庫,如果有以下幾個方面的優(yōu)勢,是可以考慮的:

      a. 代碼自動生成,可以提高開發(fā)效率

       

      b. 封裝后更不容易出錯,這也可以做,畢竟很多開發(fā)隊伍中,都有新手。

       

      c. 減少代碼量。

       

      d. 提供 Ado.net 或者數(shù)據(jù)庫驅(qū)動沒有的額外功能

      比如 Hibernate 的緩存(單表按主鍵查詢,查詢多次,實際只會執(zhí)行一次,這里是假設(shè)數(shù)據(jù)在短時間內(nèi)不會被其他人更改,利用緩存提高性能)。又比如,Ado.net 之后,微軟相繼發(fā)布 linq to sql, EF, 但是這兩個都只支持 SQL Server ,于是很多人做出類似的、支持其他數(shù)據(jù)庫的 linq/EF,拿出來賣,也不錯。

       

      從“CPQuery, 解決拼接SQL的新方法” 這篇文章所說,以上幾點,它都沒有做到。因此,這個 CPQuery 是沒有什么用處的。

       

      至于該文提到的幾點,都是錯誤的:

      2. 可能會影響性能:每條SQL語句都需要數(shù)據(jù)庫引擎執(zhí)行[語句分析]之類的開銷。

      3. 影響代碼的可維護性:SQL語句與C#混在一起,想修改SQL就得重新編譯程序,而且二種代碼混在一起,可讀性也不好。

       

      在數(shù)據(jù)庫系統(tǒng)中,SQL 的解析時間,基本可以忽略不計。相對于 SQL 及結(jié)果數(shù)據(jù)在網(wǎng)絡(luò)中傳輸、SQL查詢數(shù)據(jù)的搜索時間,那么一點點 SQL 的解析時間,根本可以忽略。所謂 SQL 解析時間要優(yōu)化,純粹是學(xué)院派的胡說。

      至于 SQL語句與C#混在一起,這個要看個人的寫程序風(fēng)格了。用 Ado.net 還是用 CPQuery,都有這個問題。因此,這不是 CPQuery 的優(yōu)點。

       

      用 Ado.net 也可以寫成這樣的函數(shù):

      GetUploadData(uploadFlag), 然后把上面的代碼放在里面。這樣僅僅數(shù)據(jù)庫相關(guān)的代碼在一起,其他代碼都在這個 GetUploadData 外面,也沒有什么“SQL語句與C#混在一起”的問題。

      至于“想修改SQL就得重新編譯程序”,這是避免不了的。如果從業(yè)務(wù)邏輯上看,需要把 SQL 中的 > 改成 >= ,確實需要重新編譯程序。用 CPQuery 還是用 Ado.net ,都是如此。

       

      我個人覺得,CPQuery 的作者 fish-li ,對  Ado.net 的不熟悉,才導(dǎo)致了他寫出了 CPQuery 。這本沒有什么。Hibernate 的作者也是不愿意手工寫 SQL 才弄出了一個 Java ORM,但是人家有自己的賣點:通過反射來把結(jié)果集數(shù)據(jù),填充到 java 對象里,不用一個個字段賦值;通過緩存,單表按主鍵查詢,查詢多次,實際只會執(zhí)行一次,提高性能。這兩個賣點,都是 Java JDBC 本身沒有的。

      CPQuery 提供了什么 Ado.net 缺乏的東西么?看不到。

       

      所以說,這個 CPQuery 沒有什么用處。

      posted @ 2012-09-11 10:06  杰克倫敦塵  Views(5728)  Comments(185)    收藏  舉報
      歡迎大家下載試用折桂單點登錄系統(tǒng), https://www.zheguisoft.com
      主站蜘蛛池模板: 一区二区三区黄色一级片| 资源在线观看视频一区二区| 国产99视频精品免费专区| 亚洲精品免费一二三区| 精品视频在线观看免费观看| 2020国产成人精品视频| 熟妇女人妻丰满少妇中文字幕| AI做受???高潮AAAA视频| 东京热av无码电影一区二区| 在线天堂最新版资源| 亚洲乱妇熟女爽到高潮的片| 久久羞羞色院精品全部免费| 亚洲人成电影网站色mp4| 四虎永久播放地址免费| www插插插无码免费视频网站| 大帝AV在线一区二区三区| 成人区人妻精品一区二蜜臀 | 亚洲av成人午夜福利| 亚洲色欲或者高潮影院| 亚洲综合久久精品国产高清| 乱妇乱女熟妇熟女网站| 国产日韩乱码精品一区二区| 无码AV无码免费一区二区| 2019久久久高清日本道| 国产精品无码a∨麻豆| 国产成人一区二区视频免费| 亚洲国产精品老熟女乱码| 国产精品看高国产精品不卡| 亚洲国产大胸一区二区三区| 亚洲色拍拍噜噜噜最新网站| 亚洲理论在线A中文字幕| 国内精品自产拍在线播放| 性色在线视频精品| 一本高清码二区三区不卡| 九台市| jizzjizz日本高潮喷水| 亚洲第一区二区快射影院| 伊人久久精品无码麻豆一区| 日韩 一区二区在线观看| 午夜成人鲁丝片午夜精品| 国产精品中文字幕第一页|