亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在C#中建立復雜的、靈活的SQL查詢/命令

2019-11-18 16:58:47
字體:
來源:轉載
供稿:網友

原文地址:http://www.codePRoject.com/cs/database/SelectQueryBuilder.asp

SelectQueryBuilder類允許在你的代碼中建立復雜的SQL語句和命令。它也能幫助于避免SQL注入式攻擊。

介紹
       承認,并且我們都這樣作過,也認為下面的方式是最好的和唯一的方式。就是我們建立大量的字符串包含所有的Where子句,然后提交到數據庫去執行它。來斷的加語句到我們的SQL字符串,極有可能會帶來Bugs和SQL注入式攻擊的危險。并且也使得我們的代碼更難看也不易于管理。

       這種情況必須停止,但如何停止?有人說使用存儲過程。但它并沒有真正的解決這個問題。你還得動態建立你的SQL語句,只不過有問題移到數據庫層面上了,依然有SQL注入的危險。除了這個“解決方案”外,可能還有非常多的選擇供你考慮,但它們都會帶來一個基本的挑戰:讓SQL語句工作的更好、更安全。

       當我從我的在線DAL(數據訪問層)生成工具http://www.code-engine.com/建立C#模板時,我想提供一個易于使用的方法來定制查詢數據。我不再想使用“字符串查詢”(我以前開發的模板)來查詢數據。我厭煩這種凌亂的方式來得到數據。我想用一種清晰的、直覺的、靈活的、簡單的方式從表中選擇數據,聯接一些別的語句,使用大量的Where子句,用一些列來分組數據,返回前X個記錄。

       我開始開發所想的有這種嚴密功能的SelectQueryBuilder類。它暴露了許多屬性和方法,你能很容易地在Select語句中使用它們。一旦調用BuildQuery()和BuildCommand()方法,它能提供一種更好的舊的“字符串查詢“或可以使用命令參數的DbCommand對象來查詢數據。

使用代碼
舊的方式的代碼
       下面的代碼闡明了以前建立SELECT語句的方法,它使用許多類變量來說明應該使用那種連接操作(WHERE,或者OR),同時也給你的數據庫帶來了可能的SQL注入式攻擊。

 

string statement = "SELECT TOP " + maxRecords + " * FROM Customers ";

string whereConcatenator = "WHERE ";

 

if (companyNameTextBox.Text.Length > 0)

{

    statement += whereConcatenator;

    statement += "CompanyName like '" + companyNameTextBox.Text + "%' ";

    whereConcatenator = "AND ";

}

if (cityTextBox.Text.Length > 0)

{

    statement += whereConcatenator;

    statement += "City like '" + cityTextBox.Text + "%' ";

    whereConcatenator = "AND ";

}

if (countryComboBox.SelectedItem != null)

{

    statement += whereConcatenator;

    statement += "Country = '" + countryComboBox.SelectedItem + "' ";

    whereConcatenator = "AND ";

}

       我相信上面的代碼對你來說是非常熟悉的,你可能在過去的十多年一直是這樣使用的,或者你曾經編碼過數據庫驅動的搜索功能。讓我告訴你這種思想:這種查詢你的數據庫的方法不能再使用了,它是難看的也是不安全的。

SelectQueryBuilder方式的代碼
       同樣的查詢能夠使用SelectQueryBuilder類建立。

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectFromTable("Customers");

query.SelectAllColumns();

query.TopRecords = maxRecords;

 

if (companyNameTextBox.Text.Length > 0)

    query.AddWhere("CompanyName", Comparison.Like,

                    companyNameTextBox.Text + "%");

 

if (cityTextBox.Text.Length > 0)

    query.AddWhere("City", Comparison.Like,

                   cityTextBox.Text + "%");

 

if (countryComboBox.SelectedItem != null)

    query.AddWhere("Country", Comparison.Equals,

                  countryComboBox.SelectedItem);

 

string statement = query.BuildQuery();

 

// or, have a DbCommand object built

// for even more safety against SQL Injection attacks:

query.SetDbProviderFactory(

      DbProviderFactories.GetFactory(

      "System.Data.SqlClient"));

DbCommand command = query.BuildCommand();

       你能看到,這種方式比直接使用連接字符串更直觀??紤]到第一個例子SQL注入的危險,通過SelectQueryBuilder建立的SELECT查詢是非常安全的,并不用擔心使用的TextBoxs中的內容。事實上它也非常簡單!

使用SQL函數
       如果你想在你的查詢中使用SQL函數,你能使用SqlLiteral類來打包函數的調用。說明這個類能作什么的最好方式就是給你顯示一小段代碼例子:

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectFromTable("Orders");

query.AddWhere("OrderDate", Comparison.LessOrEquals,

                       new SqlLiteral("getDate()"));

       如果我們沒有打包getDate()函數調用到SqlLiteral類中,建立的查詢就會產生WHERE子句:OrderDate<=’getDate()’。當然,我們希望在語句中的這個函數沒有被單引號包圍。這時SqlLiteral就可以派上用場了:它直接拷貝字符串到輸出,并沒有把它格式化成字符串?,F在的輸出WHERE子句應當是OrderDate<=getDate()!

查詢中使用JOINs
       要創建到其它表的JOINs,你能使用AddJoin方法。下面的代碼顯示了如何創建一個從Ordres表到Customers表的INNER JOIN。

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectFromTable("Orders");

 

query.AddJoin(JoinType.InnerJoin,

              "Customers", "CustomerID",

              Comparison.Equals,

              "Orders", "CustomerID");

 

query.AddWhere("Customers.City",

      Comparison.Equals, "London");

       這段代碼選擇所有居住在London的客戶的訂單。一旦調用了BuildQuery方法,就會產生下面的SQL語句:

SELECT Orders.*

FROM Orders

INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID

WHERE (Customers.City = 'London')

       注意到缺省的查詢只會建立所選擇的表的selects * 語句(這個例子中的Orders.*)。如果你也想選擇連接表的列的話,你必須得顯式地選擇它們。你能通用調用query.SelectColumns(“Orders.*”,”Customers.*”)。

建立計算查詢
       如果你想對你的數據庫執行一個計算查詢。你能使用SelectCount方法如同下面顯示的:

Query.SelectCount();

       在更加復雜的計算查詢中,你可能想使用GROUP BY語句??匆幌孪旅娴睦?,它顯示了如何使用GroupBy和AddHaving方法。

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectColumns("count(*) AS Count", "Sh

query.AddOrderBy("count(*)", Sorting.Descending);

       上面的代碼選擇了每個城市的訂單數,并用訂單數目排序,不考慮來自制Amsterdam的訂單,BuildQuery方法的輸出結果應當是:

SELECT count(*) AS Count, ShipCity

FROM Orders

GROUP BY ShipCity

HAVING (ShipCity <> 'Amsterdam')   

ORDER BY count(*) DESC

復雜的Where語句
       如果你曾經用過微軟的
access或SQL Server的內置的查詢生成器的話,是否驚訝你能建立和代碼一樣的包含多層ANDs和Ors,并沒有關心()符號的位置的查詢?是的?我也能!

       你能使用SelectQueryBuilder類實現!你能加多層的WHERE語句到你的查詢。缺省,所有對query.AddWhere的調用被放在查詢的第一層上。你可以把它比作SQL Server查詢生成器的’Criteria’列;第二、三、四層等相應地對應于’Or…’列。

       看一下下面的SQL Server查詢生成器的快照,通過它我能快速地把簡單的假的SELECT語句放在一起來:

 

       如你看到的,我創建一個查詢,它選擇所有在1-1-2005日期之前的客戶’VINET’的訂單,和所有30-6-2004日期之前或1-1-2006日期之后的客戶’TOMSP’的訂單(請不要問為什么有人想查詢某個人的訂單,這僅僅是一個 例子)。這個查詢能夠建立:

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectFromTable("Orders");

 

// Add 'Criteria' column to level 1

query.AddWhere("CustomerID", Comparison.Equals,

                                   "VINET", 1);

query.AddWhere("OrderDate", Comparison.LessThan,

                     new DateTime(2005,1,1), 1);

 

// Add first 'Or...' column to level 2

query.AddWhere("CustomerID", Comparison.Equals, "TOMSP", 2);

query.AddWhere("OrderDate", Comparison.LessThan,

                    new DateTime(2004,6,30), 2);

 

// Add second 'Or...' column to level 3

query.AddWhere("CustomerID", Comparison.Equals,

                                   "TOMSP", 3);

query.AddWhere("OrderDate", Comparison.GreaterThan,

                        new DateTime(2006,1,1), 3);

       當調用 BuildQuery時,所有定義的層將被OR到一起,幾乎和SQL Server生成的一樣。

       如果你到所產生的語句接近一樣時,想讓查詢更復雜,你可能會說“我的放兩個隨后的語句一起放在一個語句中,在兩個日期間使用OR”。你能夠這樣作。在SQL Server查詢生成器中,這個查詢看起來像:

 

       同樣,它也可能使用SelectQueryBuilder通過創建’嵌套的WHERE子句’來實現。

SelectQueryBuilder query = new SelectQueryBuilder();

query.SelectFromTable("Orders");

 

// Add 'Criteria' column to level 1

query.AddWhere("CustomerID", Comparison.Equals, "VINET", 1);

query.AddWhere("OrderDate", Comparison.LessThan,

                     new DateTime(2005,1,1), 1);

 

// Add 'Or...' column to level 2

query.AddWhere("CustomerID",

                Comparison.Equals, "TOMSP", 2);

 

// Add the date selection clause

WhereClause clause =

    query.AddWhere("OrderDate", Comparison.LessThan,

                        new DateTime(2004,6,30), 2);

 

// Add a nested clause to the captured clause

clause.AddClause(LogicOperator.Or,

       Comparison.GreaterThan, new DateTime(2006,1,1));

       注意到我用了一個WhereClause對象,它由AddWhere調用返回。接著調用clause.AddClause創建一個嵌套的子句柄,并且選擇通過指定LogicOperator.Or來把它OR到第一個子句上。所產生的語句如下:

SELECT Orders.*

FROM Orders

WHERE

(

    (CustomerID = 'VINET')

    AND (OrderDate < '2005/01/01 12:00:00')

)

OR

(

    (CustomerID = 'TOMSP')

    AND (OrderDate < '2004/06/30 12:00:00' OR

         OrderDate > '2006/01/01 12:00:00')

)

       請注意這個例子中日期包含’12:00:00’,這是因為我在DateTime構造體中忽略了時間。但這只要由于我的習慣。如果我使用new DateTime(2006,1,1,0,0,0),日期字符串將包含’00:00:00’。

結論
       在介紹中我就提到,SelectQueryBuilder是CodeEngine框架的一部分。這個框架 也包含了DeleteQueryBuilder,UpdateQueryBuilder,InsertQueryBuilder。我在通過我的C#DAL產生器生成的代碼中使用這些生成器。你能從www.code-engine.com上下載一份 框架DLL的拷貝。在這期間我也將發布其它的查詢生成器的源代碼。同時如果你有什么問題,評價或建議,請及時與我聯系。

http://www.49028c.com/yxy21969/archive/2006/09/20/509154.html


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品中文字幕有码专区| 久久偷看各类女兵18女厕嘘嘘| 最新亚洲国产精品| 国产精品电影久久久久电影网| 久久久999成人| 亚洲男人天堂手机在线| 日韩视频欧美视频| 2020国产精品视频| 国产91精品网站| 影音先锋欧美在线资源| 国产日本欧美一区二区三区在线| 国产91在线播放精品91| 在线观看视频亚洲| 亚洲新声在线观看| 色99之美女主播在线视频| 久久亚洲精品中文字幕冲田杏梨| 久久中文字幕在线| 超碰97人人做人人爱少妇| 亚洲品质视频自拍网| 色青青草原桃花久久综合| 日本欧美一二三区| 韩曰欧美视频免费观看| 亚洲成人久久久久| 国产亚洲日本欧美韩国| 日韩在线激情视频| 全亚洲最色的网站在线观看| 国产美女久久精品| 在线亚洲男人天堂| 国产精品永久免费观看| 国产精品第3页| 国产精品久久久久久久久借妻| 国产婷婷色综合av蜜臀av| 一个人www欧美| 亚洲精品色婷婷福利天堂| 国产精品专区第二| 91久久久久久久久久久久久| 777国产偷窥盗摄精品视频| 丰满岳妇乱一区二区三区| 欧美精品在线免费| 性金发美女69hd大尺寸| 亚洲情综合五月天| 国产女精品视频网站免费| 久久这里只有精品视频首页| 日韩中文视频免费在线观看| 福利微拍一区二区| 久久久综合av| 亚洲国产精品一区二区久| 成人h猎奇视频网站| 欧美亚洲视频一区二区| 亚洲成人久久电影| 欧美激情一区二区三区久久久| 久久精品国产欧美亚洲人人爽| 亚洲一区二区三区成人在线视频精品| 日韩美女福利视频| 日本视频久久久| 成人激情春色网| 日本亚洲欧美成人| 国产女同一区二区| 欧美日韩国产一区二区三区| 欧美日韩国产999| 久久久这里只有精品视频| 久久久久这里只有精品| 欧美日韩一区二区精品| 国产99久久精品一区二区 夜夜躁日日躁| 97超视频免费观看| 亚洲免费电影在线观看| 欧美极品欧美精品欧美视频| 久久天天躁狠狠躁夜夜躁2014| 欧美三级免费观看| 一区二区三区视频在线| 久久在线观看视频| 欧美大成色www永久网站婷| 久久精品久久久久久国产 免费| 奇米影视亚洲狠狠色| 日韩精品在线观看一区二区| 亚洲经典中文字幕| 成人综合网网址| 欧洲成人免费视频| 国产欧美日韩免费看aⅴ视频| 高清在线视频日韩欧美| 日韩在线观看成人| 欧美精品久久一区二区| 98视频在线噜噜噜国产| 丝袜美腿亚洲一区二区| 亚洲美女av黄| 精品视频久久久久久久| 国产欧美日韩最新| 中文字幕av一区中文字幕天堂| 久久精品在线视频| 国产精品欧美风情| 清纯唯美日韩制服另类| 国产精品普通话| 欧洲精品毛片网站| 国产精品久久久久久久久久久不卡| 久久久精品一区二区三区| 伊人久久久久久久久久| 欧美久久精品一级黑人c片| 成人免费网站在线| 日韩欧美国产骚| 黑人巨大精品欧美一区二区| 亚洲国产小视频在线观看| 久久国产精品久久精品| 亚洲第一视频网站| 国内精品久久久久| 久久久国产在线视频| 精品国产一区av| 亚洲免费精彩视频| 91中文精品字幕在线视频| 九九九久久久久久| 在线观看精品国产视频| 久久久免费高清电视剧观看| 国产日韩av在线播放| 国产视频在线一区二区| 欧美国产日韩一区二区在线观看| 97在线视频一区| 日韩免费观看在线观看| 91高清在线免费观看| 亚洲最大成人免费视频| 亚洲国产一区自拍| 国产精品视频一| 色午夜这里只有精品| 久久久久久综合网天天| 国产男女猛烈无遮挡91| 欧美成人精品激情在线观看| 国产伦精品免费视频| 亚洲精品中文字幕女同| 亚洲国产精品久久久久秋霞蜜臀| 亚洲新声在线观看| 国产精品高清免费在线观看| 久久精品国产成人| 亚洲bt天天射| 九九精品在线视频| 亚洲欧洲一区二区三区在线观看| 亚洲图片欧洲图片av| 亚洲社区在线观看| 国产精品 欧美在线| 91久久精品美女高潮| 欧美电影免费观看高清完整| 久久91超碰青草是什么| 欧美日韩亚洲精品内裤| 欧美多人乱p欧美4p久久| 欧美老女人性视频| 亚洲色图综合久久| 久久精品视频网站| 亚洲欧美另类中文字幕| 亚洲精品美女在线| 日韩不卡在线观看| 免费97视频在线精品国自产拍| 尤物精品国产第一福利三区| 国产精品久久97| 中文字幕一区二区三区电影| 日韩欧美国产免费播放| 日韩免费在线看| 久久久电影免费观看完整版| 国产免费一区二区三区香蕉精| 亚洲美女av电影| 91影院在线免费观看视频| 一本色道久久88综合日韩精品| 亚洲美女在线看| 97久久国产精品| 精品久久久国产精品999| 夜夜嗨av色综合久久久综合网| 欧美午夜www高清视频| 国产精品免费一区二区三区都可以|