欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

C# SQL文件執(zhí)行器的功能實(shí)現(xiàn)

系統(tǒng) 2133 0

好一段時(shí)間沒(méi)寫(xiě)博客了,這次我們來(lái)一起談?wù)凷QL文件執(zhí)行器的功能實(shí)現(xiàn),在ERP軟件升級(jí)時(shí)往往在客戶(hù)端程序更新的同時(shí)也要對(duì)數(shù)據(jù)庫(kù)進(jìn)行升級(jí),ERP程序開(kāi)發(fā)人員會(huì)對(duì)數(shù)據(jù)庫(kù)升級(jí)的執(zhí)行代碼在開(kāi)發(fā)的過(guò)程中以SQL文件的形式記錄下來(lái)或者保存到特定格式的文件中供軟件升級(jí)時(shí)使用,有些ERP軟件會(huì)附帶開(kāi)發(fā)數(shù)據(jù)庫(kù)升級(jí)工具來(lái)方便實(shí)施人員執(zhí)行軟件升級(jí)操作或者ERP軟件內(nèi)置數(shù)據(jù)庫(kù)升級(jí)功能,不管使用什么樣的方式能達(dá)到軟件升級(jí)的目的就是好方法,這次我們就來(lái)剝離這部分的功能來(lái)實(shí)現(xiàn)一個(gè)SQL文件執(zhí)行器,不特定于SQL文件,只要文件里面包含有SQL語(yǔ)法,而且能正常得到執(zhí)行,在本執(zhí)行器中就能正確的執(zhí)行它(本次我們主要爭(zhēng)對(duì)SQL文件,其他格式文件只要把相關(guān)控制去掉就好了,只是得不到很好的控制比較亂,或者你有更好的方法)。介紹性引入就到此為止了,接下來(lái)我們開(kāi)始進(jìn)入主題,研究一下SQL執(zhí)行器的原理及設(shè)計(jì)思路吧。

一、SQL文件執(zhí)行器原理分析

???????? 在分析原理之前,我們先來(lái)規(guī)范一下SQL文檔的書(shū)寫(xiě),我們?cè)谝粋€(gè)SQL語(yǔ)句結(jié)束的時(shí)候換行來(lái)個(gè)GO關(guān)鍵字再換行繼續(xù)書(shū)寫(xiě)下一個(gè)SQL語(yǔ)句,遇到“USE [數(shù)據(jù)庫(kù)名] ”語(yǔ)句時(shí)希望能把此語(yǔ)句單獨(dú)放一行。做到以上書(shū)寫(xiě)規(guī)范我們開(kāi)始原理分析:

1.上述SQL規(guī)范居然都做到了但是SQL文件里面的內(nèi)容還不是我想要的,我想重新規(guī)范一下我的SQL文檔,我想理想化它,所以我需要對(duì)SQL文件進(jìn)行重新洗牌,我想我應(yīng)該一行一行的閱讀它,并把它提取出來(lái)去掉前后的空格,我應(yīng)該重組改文件的內(nèi)容并且在讀取每一行的同時(shí)在其末尾寫(xiě)入一個(gè)換行回車(chē)符,而且我還想統(tǒng)計(jì)出每一個(gè)SQL文件中的SQL語(yǔ)句的個(gè)數(shù)(循環(huán)時(shí)會(huì)用到),我用GO關(guān)鍵字來(lái)標(biāo)記了SQL語(yǔ)句的個(gè)數(shù),在閱讀到一行去掉首尾空格后只剩下不區(qū)分大小寫(xiě)的GO時(shí)我的統(tǒng)計(jì)會(huì)+1(統(tǒng)計(jì)從1開(kāi)始),哦,這還永遠(yuǎn)不夠,我還沒(méi)考慮到USE關(guān)鍵字的處理,通常會(huì)選擇一個(gè)數(shù)據(jù)庫(kù)來(lái)執(zhí)行相應(yīng)的SQL文件,USE關(guān)鍵字在切換著數(shù)據(jù)庫(kù),我需要在檢測(cè)到USE語(yǔ)句時(shí)切換數(shù)據(jù)庫(kù)為USE后面跟著的數(shù)據(jù)庫(kù)來(lái)執(zhí)行后面的代碼,所以我要把USE語(yǔ)句單獨(dú)剝離開(kāi)來(lái)以待做特殊的處理,往往我們寫(xiě)SQL文件的時(shí)候在USE語(yǔ)句的前后都不帶GO關(guān)鍵字的,我需要給它加上。 有一個(gè)需要注意的地方:USE [數(shù)據(jù)庫(kù)名]? 后面直接跟著SQL語(yǔ)句的(沒(méi)有回車(chē)換行),這種寫(xiě)法在語(yǔ)法上是完全正確的,但是看上去就不是很美觀了,這種方式我這邊就不做處理了,請(qǐng)遵守上述規(guī)范吧,再處理下去程序性能就嚴(yán)重下降啦,本程序在數(shù)據(jù)庫(kù)切換時(shí)是從USE 之后的字符開(kāi)始到回車(chē)換行符結(jié)束來(lái)取數(shù)據(jù)庫(kù)名的,這種寫(xiě)法會(huì)引發(fā)SQL異常。 我需要構(gòu)建一個(gè)這樣的方法。

2.在第一點(diǎn)里面我們對(duì)SQL文件進(jìn)行了格式化,現(xiàn)在開(kāi)始我希望以GO關(guān)鍵字作為分割點(diǎn),把SQL文件里面的SQL語(yǔ)法進(jìn)行分段,我希望一段段的得到執(zhí)行并返回執(zhí)行結(jié)果,此時(shí)我需要一個(gè)循環(huán)來(lái)遍歷文件中的SQL語(yǔ)句并執(zhí)行它。本工具名字叫做SQL文件執(zhí)行器很顯然是爭(zhēng)對(duì)批量SQL文件的處理的,所以一個(gè)循環(huán)是永遠(yuǎn)不夠的,我還得在外面再套一個(gè)循環(huán)來(lái)遍歷所有的SQL文件,對(duì)每個(gè)SQL文件進(jìn)行分析并遍歷其中的SQL語(yǔ)句執(zhí)行它,這樣就達(dá)到我們的目的了。貌似還有一個(gè)問(wèn)題未處理,比如在執(zhí)行到一半的時(shí)候我不執(zhí)行了需要強(qiáng)制停止他這如何是好呢,強(qiáng)制關(guān)閉程序很顯然是不可取的很容易引發(fā)未知的數(shù)據(jù)庫(kù)異常或者造成數(shù)據(jù)丟失這些狀況都是我們不想看到的,那么有什么好辦法呢?此時(shí)我啟用了臭名遠(yuǎn)揚(yáng)的goto語(yǔ)句來(lái)從深層嵌套循環(huán)中跳出循環(huán),我讓他在用戶(hù)發(fā)出停止指令后在執(zhí)行完當(dāng)前的SQL語(yǔ)法段后跳出循環(huán),從而停止接下來(lái)的SQL語(yǔ)法的執(zhí)行,這樣子保障了SQL數(shù)據(jù)的安全,在SQL文件執(zhí)行的期間,程序是不允許關(guān)閉的,除非向程序發(fā)出停止指令,并成功停止的時(shí)候,才允許程序關(guān)閉。

很簡(jiǎn)單的一個(gè)程序,我就大致的做以上兩點(diǎn)的原理分析吧,接下來(lái)我上傳下我的程序界面設(shè)計(jì)圖吧,大家參考下:

C# SQL文件執(zhí)行器的功能實(shí)現(xiàn)

接下來(lái)我貼上來(lái)一些主要源代碼供參考,代碼可能看上去有些難懂,表述性不是很好,期待大家來(lái)改進(jìn)它:

這是對(duì)SQL文件中的語(yǔ)法進(jìn)行重新洗牌的方法

            /// <summary>

        /// 讀取文件內(nèi)容(SQL關(guān)鍵字特殊處理主要針對(duì)GO關(guān)鍵字)

        /// </summary>

        /// <param name="path">文件路徑</param>

        /// <param name="keywords">關(guān)鍵字</param>

        /// <param name="str">輸出字符串</param>

        /// <param name="i">keywords的個(gè)數(shù)</param>

        public void FileReader(string path,string keywords,out int i,out string str)

        {

            bool useplusgo = false;//use后面是否跟著go

            bool goplususe = false;//use前面是否存在go

            StreamReader sr = new StreamReader(path, Encoding.GetEncoding("GB2312"));

            //str = sr.ReadToEnd();

            string s = null;

            string temp = null;

            int x = 0;

            while ((temp = sr.ReadLine()) != null)

            {

                if (temp.Trim().ToUpper() == keywords.ToUpper())

                {

                    useplusgo = false;//use語(yǔ)句后面跟著go則關(guān)閉use判斷

                    goplususe = true;//use前面存在go

                    x++;

                    s += "\r\n" + keywords + "\r\n  \r\n";

                }

                else if (temp.Trim().Length >= 4 && temp.Trim().ToUpper().Substring(0, 4).Trim() == "USE")

                {

                    temp = temp.Trim().Replace("[", "").Replace("]", "");

                    //如果use前面不存在go則加上

                    if (!goplususe && s != "\r\n" && s != null)

                    {

                        x++;

                        s += "\r\n" + keywords + "\r\n\r\n" + temp + "\r\n";

                    }

                    else

                    {

                        s += temp + "\r\n";

                    }

                    useplusgo = true;

                }

                else

                {

                    goplususe = false;//go后面不跟use關(guān)閉判斷

                    //如果use后面不跟go則加上go

                    if (useplusgo)

                    {

                        x++;

                        s += "\r\n" + keywords + "\r\n" + temp + "\r\n";

                        useplusgo = false;//關(guān)閉use判斷

                    }

                    else

                    {

                        s += temp + "\r\n";

                    }

                }

            }

            i = x;

            str = s;

            sr.Close();//關(guān)閉當(dāng)前打開(kāi)的文件

        }
  


這個(gè)是處理USE語(yǔ)句的方法

            /// <summary>

        /// 獲取use后面的數(shù)據(jù)庫(kù)名稱(chēng)

        /// </summary>

        /// <param name="str">use字符串行</param>

        /// <returns></returns>

        public string UseStatementProcessing(string str)

        {

            string[] strSplit = Regex.Split(str, "\r\n", RegexOptions.IgnoreCase);

            int x = strSplit.Length;

            string s = "";

            if (/*strSplit[0].ToUpper().IndexOf("USE ", 0) >= 0*/Regex.IsMatch(strSplit[0].ToUpper(), "USE ", RegexOptions.IgnoreCase))

            {

                s = strSplit[0].Substring(4, strSplit[0].Length - 4).Trim();

            }

            else if (/*strSplit[1].ToUpper().IndexOf("USE ", 0) >= 0*/Regex.IsMatch(strSplit[1].ToUpper(), "USE ", RegexOptions.IgnoreCase))

            {

                s = strSplit[1].Substring(4, strSplit[1].Length - 4).Trim();

            }

            else

            {

                s = "";

            }

            return s;

        }
  


這次話題就到此為止吧,這程序比較簡(jiǎn)單,大家可以寫(xiě)寫(xiě)玩,當(dāng)作練練手也不錯(cuò),主要在于文件的操作和字符串的處理。

?

C# SQL文件執(zhí)行器的功能實(shí)現(xiàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 色呦呦tv | 91视频首页| 香蕉成人国产精品免费看网站 | 亚洲激情视频 | 日韩精品在线一区 | 国产福利不卡视频在免费 | 九九热线精品视频6一 | 欧美午夜影院 | 国产综合亚洲精品一区二 | 骚视频在线观看 | 国产99视频在线 | 国产成人av电影 | 91看片网 | 五月六月婷婷 | 国产综合久久久久影院 | 成人网免费视频 | 欧美精品人爱a欧美精品 | 日本aaaaa高清免费看 | 偷拍亚洲制服另类无码专区 | 日韩 亚洲 欧美 中文 高清 | 蜜桃精品久久久久久久免费影院 | 性色av一区二区三区四区 | 免费香蕉视频 | 一级毛片国产真人永久在线 | 亚洲码专区 | 日本免费网站 | 大学生一级毛片全黄毛片黄 | 欧美视频在线观看一区二区 | 美女露尿口视频 | 成人在线视频网站 | 久久久久亚洲 | 国产福利精品在线观看 | www午夜视频 | 久久另类视频 | 狠狠干伊人网 | 国产福利视屏 | 美女污污视频在线观看 | 97超碰免费 | 久久久国产一区二区三区 | 一级黄色毛片子 | 日本一区二区三区四区在线观看 |