我在HIT第一次.net實驗中用到的sql語句

這次實驗主要是開發基於.net framework的窗體應用程序。我感覺這次實驗讓我學到了挺多東西。我做的是一個加州招待所管理系統,就是瞎扯淡。。囧。。。

第一就是儘量減少模塊(不知道寫了個這麼水的實驗能不能稱得上是模塊,暫時先這麼叫着吧,顯得牛B一點)之間的耦合性,這個特別重要。之前總是聽一些什麼減少模塊之間的耦合的觀點,沒有意識到有什麼用,以爲是用來裝B的,但是這次讓我深深地意識到了這個advice的重要性。我對這個advice的理解就是各部分分工要非常明確,負責processing data的專門processing data,負責操作UI的專門來操作UI,諸如此類。這個在android的開發中也有所體現,即intent的機制。

此外感覺總是對數據庫的增刪改查沒啥意思,於是就想通過將sql語句設計的複雜一點來幫助分擔一些程序邏輯的複雜程度。

第一在這個實驗中完全是用來裝B的,就是數據庫的分頁查詢與分頁顯示,這個功能在一些實際的應用中比較有用,例如當數據量很大時,不可能一次都讀出來。

"select top " + NUMBER_IN_A_PAGE + " * from " + DBKEYS.ROOM_INFO_TABLE_NAME
                + " where RoomNumber not in (select top " + page * NUMBER_IN_A_PAGE + " RoomNumber from " + DBKEYS.ROOM_INFO_TABLE_NAME + ")";
其中NUMBER_IN_A_PAGE是每頁的數量,對應的C#代碼如下:

這個函數是查詢數據庫,返回一個DataSet供填充DataGridView使用:

        /// <summary>
        /// 根據給定的sql字符串查詢數據,返回結果DataSet,flag爲區分函數重載標誌
        /// </summary>
        /// <param name="sqlString"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        public DataSet inquiry(String sqlString,Boolean flag)
        {
            SqlCommand command;
            SqlDataAdapter adapter;
            DataSet dataSet;
            try
            {
                command = new SqlCommand(sqlString, connection);
                adapter = new SqlDataAdapter(command);
                dataSet = new DataSet();
                adapter.Fill(dataSet);
                return dataSet;
            }
            catch (SqlException e)
            {
                Console.WriteLine(e.Message + flag);
                return null;
            }
        }
        /// <summary>
        /// 設置setDataGridView的顯示
        /// </summary>
        private Boolean setDataGridView(int page)
        {
            String sqlString = "select top " + NUMBER_IN_A_PAGE + " * from " + DBKEYS.ROOM_INFO_TABLE_NAME
                + " where RoomNumber not in (select top " + page * NUMBER_IN_A_PAGE + " RoomNumber from " + DBKEYS.ROOM_INFO_TABLE_NAME + ")";
            DataSet dataSet = dao.inquiry(sqlString, true);
            // 說明沒有查到結果,到達了頁首或者頁尾
            if (dataSet == null || dataSet.Tables.Count == 0 || dataSet.Tables[0].Rows.Count <= 0)
            {
                return false;
            }
            DataTable tableFirst = dataSet.Tables[0]; // 用DataTable 取 DataSet中的第一個表
            // 設置DataGridView的列名
            foreach (DataColumn dc in tableFirst.Columns)
            {
                RoomInfoDataGridView.Columns.Add(dc.ColumnName, dc.ColumnName);
            }
            // 每次新建一行將數據填到DataGridView中
            foreach (DataRow dr in tableFirst.Rows)
            {
                DataGridViewRow vr = new DataGridViewRow();
                foreach (DataGridViewColumn dc in RoomInfoDataGridView.Columns)
                {
                    vr.Cells.Add(dc.CellTemplate.Clone() as DataGridViewCell);
                    vr.Cells[vr.Cells.Count - 1].Value = dr[dc.Name];
                }
                RoomInfoDataGridView.Rows.Add(vr);
            }
            // 設置RoomInfoDataGridView禁止根據列排序
            int i;
            for (i = 0; i < this.RoomInfoDataGridView.Columns.Count; i++) { }
            this.RoomInfoDataGridView.Columns[--i].SortMode = DataGridViewColumnSortMode.NotSortable;
            return true;
        }

還有一個sql語句是日期的比較,簡單說來就是給定個date,選出date在ExpectiveLiveDate和從ExpectiveLiveDate算起ExpextiveLastingTime天后之間的記錄。

"select * from VisitorBookInfo where ( '" + date + "'"
                +" between ExpectiveLiveDate and dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate))";

對應的C#函數:

        /// <summary>
        /// 根據查詢日期填充表格
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private Boolean setDataGridView(String date)
        {
            String sqlString = "select * from VisitorBookInfo where ( '" + date + "'"
                +" between ExpectiveLiveDate and dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate))";
            DataSet dataSet = dao.inquiry(sqlString, true);
            // 說明沒有查到結果
            if (dataSet == null || dataSet.Tables.Count == 0 || dataSet.Tables[0].Rows.Count <= 0)
            {
                return false;
            }
            DataTable tableFirst = dataSet.Tables[0]; // 用DataTable 取 DataSet中的第一個表
            // 設置DataGridView的列名
            foreach (DataColumn dc in tableFirst.Columns)
            {
                RoomInfoDataGridView.Columns.Add(dc.ColumnName, dc.ColumnName);
            }
            // 每次新建一行將數據填到DataGridView中
            foreach (DataRow dr in tableFirst.Rows)
            {
                DataGridViewRow vr = new DataGridViewRow();
                foreach (DataGridViewColumn dc in RoomInfoDataGridView.Columns)
                {
                    vr.Cells.Add(dc.CellTemplate.Clone() as DataGridViewCell);
                    vr.Cells[vr.Cells.Count - 1].Value = dr[dc.Name];
                }
                RoomInfoDataGridView.Rows.Add(vr);
            }
            // 設置RoomInfoDataGridView禁止根據列排序
            int i;
            for (i = 0; i < this.RoomInfoDataGridView.Columns.Count; i++) { } 
            this.RoomInfoDataGridView.Columns[--i].SortMode = DataGridViewColumnSortMode.NotSortable;
            return true;
        }

這個sql語句是選出某一層的房間,就是比如我要選出7樓的房間,也就是選出所有房間號以7開頭的,比如702,711等:

"select * from RoomInfo where(ASCII(RoomNumber) = ASCII('" + level +"'))"

對應的C#函數:

        /// <summary>
        /// 根據樓層填充表格,flag爲重載函數標誌
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private Boolean setDataGridView(String level,Boolean flag)
        {
            String sqlString = "select * from RoomInfo where(ASCII(RoomNumber) = ASCII('" + level +"'))";
            DataSet dataSet = dao.inquiry(sqlString, true);
            // 說明沒有查到結果
            if (dataSet == null || dataSet.Tables.Count == 0 || dataSet.Tables[0].Rows.Count <= 0)
            {
                return false;
            }
            DataTable tableFirst = dataSet.Tables[0]; // 用DataTable 取 DataSet中的第一個表
            // 設置DataGridView的列名
            foreach (DataColumn dc in tableFirst.Columns)
            {
                RoomInfoDataGridView.Columns.Add(dc.ColumnName, dc.ColumnName);
            }
            // 每次新建一行將數據填到DataGridView中
            foreach (DataRow dr in tableFirst.Rows)
            {
                DataGridViewRow vr = new DataGridViewRow();
                foreach (DataGridViewColumn dc in RoomInfoDataGridView.Columns)
                {
                    vr.Cells.Add(dc.CellTemplate.Clone() as DataGridViewCell);
                    vr.Cells[vr.Cells.Count - 1].Value = dr[dc.Name];
                }
                RoomInfoDataGridView.Rows.Add(vr);
            }
            // 設置RoomInfoDataGridView禁止根據列排序
            int i;
            for (i = 0; i < this.RoomInfoDataGridView.Columns.Count; i++) { }
            this.RoomInfoDataGridView.Columns[--i].SortMode = DataGridViewColumnSortMode.NotSortable;
            return true;
        }

這個是比較牛B的一條語句了,同時查詢兩個表,實現的功能就是我想預定房間,給你一個預定的日期和我要預定的天數,你給我找出現在爲空的並且沒有在裝修的,而且那天沒有預定記錄的房間(貌似邏輯有點錯誤,我要預定那天的,你爲啥限制我現在必須也得爲空和現在不能在裝修?!其實刪掉那兩個等於0的查詢限制就好,不過不影響這條語句的牛B程度):

select * from RoomInfo where (RoomInfo.RoomNumber not in ((select VisitorBookInfo.RoomNumber from VisitorBookInfo where ('" + dateBegin + "' between ExpectiveLiveDate and dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate)) and (ExpectiveLiveDate between '" + dateBegin + "' and '" + dateEnd + "')or ('" + dateBegin + "'=ExpectiveLiveDate)or('" + dateEnd + "'=dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate)))))"

對應的C#函數:

        /// <summary>
        /// 根據開始日期和結束日期查詢在該日期內房間的預定情況
        /// </summary>
        /// <param name="dateBegin"></param>
        /// <param name="dateEnd"></param>
        /// <returns></returns>
        private Boolean setDataGridView(String dateBegin,String dateEnd)
        {
            //String sqlString = "select * from RoomInfo where (RoomInfo.RoomNumber not in ((select VisitorBookInfo.RoomNumber from VisitorBookInfo where not ('" + dateBegin + "' not between ExpectiveLiveDate and dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate)) and (ExpectiveLiveDate not between '" + dateBegin + "' and '" + dateEnd + "'))))";
            String sqlString = "select * from RoomInfo where (RoomInfo.RoomNumber not in ((select VisitorBookInfo.RoomNumber from VisitorBookInfo where ('" + dateBegin + "' between ExpectiveLiveDate and dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate)) and (ExpectiveLiveDate between '" + dateBegin + "' and '" + dateEnd + "')or ('" + dateBegin + "'=ExpectiveLiveDate)or('" + dateEnd + "'=dateadd(day,ExpextiveLastingTime,ExpectiveLiveDate)))))";
            DataSet dataSet = dao.inquiry(sqlString, true);
            // 說明沒有查到結果
            if (dataSet == null || dataSet.Tables.Count == 0 || dataSet.Tables[0].Rows.Count <= 0)
            {
                return false;
            }
            DataTable tableFirst = dataSet.Tables[0]; // 用DataTable 取 DataSet中的第一個表
            // 設置DataGridView的列名
            foreach (DataColumn dc in tableFirst.Columns)
            {
                RoomInfoDataGridView.Columns.Add(dc.ColumnName, dc.ColumnName);
            }
            // 每次新建一行將數據填到DataGridView中
            foreach (DataRow dr in tableFirst.Rows)
            {
                DataGridViewRow vr = new DataGridViewRow();
                foreach (DataGridViewColumn dc in RoomInfoDataGridView.Columns)
                {
                    vr.Cells.Add(dc.CellTemplate.Clone() as DataGridViewCell);
                    vr.Cells[vr.Cells.Count - 1].Value = dr[dc.Name];
                }
                RoomInfoDataGridView.Rows.Add(vr);
            }
            // 設置RoomInfoDataGridView禁止根據列排序
            int i;
            for (i = 0; i < this.RoomInfoDataGridView.Columns.Count; i++) { }
            this.RoomInfoDataGridView.Columns[--i].SortMode = DataGridViewColumnSortMode.NotSortable;
            return true;
        }

此外,記住不能用關鍵字(如“user”)作爲表和表中列的名字,否則你會很麻煩。

下面是我的界面(功能略顯單薄):







其實實驗做到什麼成度不重要,重要的是能提高自己的思考能力和代碼水平,從中有所收穫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章