用ADOQuery创建SQL Server数据库,并创建表结构、存储过程和视图
昨天做系統(tǒng)的安裝,搞這個搞到頭大,現(xiàn)在把總結(jié)寫下巴。
PS:貼上來代碼的縮進(jìn)就亂掉了
用SQL Server企業(yè)管理器導(dǎo)出的SQL文件是不能直接在ADOQuery里用的,因為ADOQuery不支持GO,不支持注釋,視圖和存儲過程的創(chuàng)建也必須放到查詢開頭,所以必須要對企業(yè)管理器導(dǎo)出的SQL文件進(jìn)行處理,才能用。
首先,導(dǎo)出SQL語句
如圖設(shè)置
?
?
?
注意這一步,“編寫主鍵、外鍵、默認(rèn)值和檢查約束腳本”別忘了選。文件格式要選ANSI,因為貌似TStrings.LoadFromFile這個方法對Unicode的文本支持不好,如果你的代碼不用TStringList讀SQL文件,那這里選什么都無所謂。選擇創(chuàng)建一個文件,可以確保結(jié)構(gòu)按照順序創(chuàng)建,免得多個文件又要搞依賴關(guān)系,分析哪個要先創(chuàng)建,麻煩。
然后,創(chuàng)建數(shù)據(jù)庫
強(qiáng)烈建議將用于創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)庫結(jié)構(gòu)的ADOQuery的ParamCheck屬性設(shè)置為False
(要是非要設(shè)置成True,后面莫名其妙報個錯,可別怨我沒攔你^_^)
將生成的SQL文件中開頭創(chuàng)建數(shù)據(jù)庫的那部分刪除(就是直到第一句use XXX這里,包含這句,也一并刪除),因為創(chuàng)建數(shù)據(jù)庫的語句我們要自己組裝。
創(chuàng)建數(shù)據(jù)庫需要知道數(shù)據(jù)庫文件和日志的存放位置(強(qiáng)迫用戶指定貌似不太禮貌,最好自動獲取到),數(shù)據(jù)庫和日志文件初始大小,數(shù)據(jù)庫名和排序規(guī)則。
取數(shù)據(jù)庫文件和日志存放位置的辦法:(我這里是把第一個庫文件的位置當(dāng)做默認(rèn)存放位置的)
ADOQuery查詢master庫:??????? SELECT TOP 1 filename FROM sysaltfiles
然后存放默認(rèn)位置就是IncludeTrailingPathDelimiter(ExtractFilePath(Trim(FieldByName('filename').AsString)))
創(chuàng)建數(shù)據(jù)庫(仍然是在master庫里執(zhí)行):
??????? SQL.Add(Format('IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N''%s'')',[teDBName.Text]));
??????? SQL.Add(Format('DROP DATABASE [%s]',[teDBName.Text]));
??????? SQL.Add(Format(
????????? 'CREATE DATABASE [%s] ON (NAME = N''%s_Data'', FILENAME = N''%s%s_Data.MDF'' , SIZE = 7, FILEGROWTH = 10%%) LOG ON (NAME = N''%s_Log'', FILENAME = N''%s%s_Log.LDF'' , SIZE = 7, FILEGROWTH = 10%%) COLLATE Chinese_PRC_CI_AS',
????????? [teDBName.Text,teDBName.Text,FDBPath,teDBName.Text,teDBName.Text,FDBPath,teDBName.Text]));
??????? ExecSQL;
這里兩個SIZE分別是數(shù)據(jù)庫文件和日志文件的初始大小,單位MB。Chinese_PRC_CI_AS為默認(rèn)排序規(guī)則
需要注意的是,如果庫正在被使用,DROP會出錯。貌似用SQLDMO可以殺掉連那個庫的進(jìn)程,可以用這個野蠻殘忍的辦法停止對庫的使用。。。
修改SQL,創(chuàng)建數(shù)據(jù)庫結(jié)構(gòu)
以下需要在剛創(chuàng)建的數(shù)據(jù)庫中執(zhí)行
1.去掉注釋(--和/* */)
??????? Mark:=False;
??????? for Index:=0 to SQLList.Count-1 do
??????? begin
????????? //--開頭
????????? TmpStr:=Trim(SQLList[Index]);
????????? if Copy(TmpStr,1,2)='--' then
??????????? SQLList[Index]:=''
????????? else begin
??????????? if Mark then
??????????? begin
????????????? if Copy(TmpStr,Length(TmpStr)-1,2)='*/' then
????????????? begin
??????????????? Mark:=False;
????????????? end;
????????????? SQLList[Index]:='';
??????????? end
??????????? else begin
????????????? if Copy(TmpStr,1,2)='/*' then
????????????? begin
??????????????? Mark:=True;
??????????????? SQLList[Index]:='';
????????????? end;
??????????? end;
????????? end;
??????? end;
2.去掉go
?????? SQLList.Text:=StringReplace(SQLList.Text,#13#10'GO'#13#10,#13#10,[rfReplaceAll,rfIgnoreCase]);
3.在CREATE VIEW前加exec
?????? SQLList.Text:=StringReplace(SQLList.Text,'CREATE VIEW ','exec(''CREATE VIEW ',[rfReplaceAll,rfIgnoreCase]);
??????? Mark:=False;
??????? for Index:=0 to SQLList.Count-1 do
??????? begin
????????? if Mark then
????????? begin
??????????? //把exec('')之中的'替換為'',否則報錯
??????????? SQLList[Index]:=StringReplace(SQLList[Index],'''','''''',[rfReplaceAll,rfIgnoreCase]);
??????????? if System.Pos('SET ',SQLList[Index])>0 then
??????????? begin
????????????? Mark:=False;
????????????? //CREATE VIEW結(jié)尾加')
????????????? SQLList[Index-1]:=SQLList[Index-1]+''')';
??????????? end;
????????? end
????????? else if System.Pos('exec(''CREATE VIEW ',SQLList[Index])>0 then
????????? begin
??????????? Mark:=True;
????????? end;
??????? end;
4.存儲過程前加exec
這里注意存儲過程中經(jīng)常出現(xiàn)SET,所以不能讓SET做為判斷'CREATE PROCEDURE 結(jié)束的標(biāo)志,而要用
SET QUOTED_IDENTIFIER OFF,只要是企業(yè)管理器導(dǎo)出的創(chuàng)建存儲過程語句,必定以SET QUOTED_IDENTIFIER OFF緊跟著創(chuàng)建語句
??????? SQLList.Text:=StringReplace(SQLList.Text,'CREATE PROCEDURE ','exec(''CREATE PROCEDURE ',[rfReplaceAll,rfIgnoreCase]);
??????? Mark:=False;
??????? for Index:=0 to SQLList.Count-1 do
??????? begin
????????? if Mark then
????????? begin
??????????? //把exec('')之中的'替換為'',否則報錯
??????????? SQLList[Index]:=StringReplace(SQLList[Index],'''','''''',[rfReplaceAll,rfIgnoreCase]);
??????????? if System.Pos('SET QUOTED_IDENTIFIER OFF',SQLList[Index])>0 then
??????????? begin
????????????? Mark:=False;
????????????? //CREATE PROCEDURE 結(jié)尾加')
????????????? SQLList[Index-1]:=SQLList[Index-1]+''')';
??????????? end;
????????? end
????????? else if System.Pos('exec(''CREATE PROCEDURE ',SQLList[Index])>0 then
????????? begin
??????????? Mark:=True;
????????? end;
??????? end;
最后
SQL.Assign(SQLList),可以執(zhí)行Query了
?
不過我覺得SQLDMO應(yīng)該有直接執(zhí)行SQL語句的功能,就是支持GO和注釋等的Transact-SQL,時間關(guān)系,沒去深入研究SQLDMO,我暫時只是把這玩藝拿來刷數(shù)據(jù)庫列表用
總結(jié)
以上是生活随笔為你收集整理的用ADOQuery创建SQL Server数据库,并创建表结构、存储过程和视图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到一大片墓地是什么意思
- 下一篇: T-SQL中REPLACE的用法_字符串