用ADOQuery创建SQL Server数据库,并创建表结构、存储过程和视图

昨天做系统的安装,搞这个搞到头大,现在把总结写下巴。

PS:贴上来代码的缩进就乱掉了

用SQL Server企业管理器导出的SQL文件是不能直接在ADOQuery里用的,因为ADOQuery不支持GO,不支持注释,视图和存储过程的创建也必须放到查询开头,所以必须要对企业管理器导出的SQL文件进行处理,才能用。

首先,导出SQL语句

如图设置

 

 

 

注意这一步,“编写主键、外键、默认值和检查约束脚本”别忘了选。文件格式要选ANSI,因为貌似TStrings.LoadFromFile这个方法对Unicode的文本支持不好,如果你的代码不用TStringList读SQL文件,那这里选什么都无所谓。选择创建一个文件,可以确保结构按照顺序创建,免得多个文件又要搞依赖关系,分析哪个要先创建,麻烦。

然后,创建数据库

强烈建议将用于创建数据库和数据库结构的ADOQuery的ParamCheck属性设置为False

(要是非要设置成True,后面莫名其妙报个错,可别怨我没拦你^_^)

将生成的SQL文件中开头创建数据库的那部分删除(就是直到第一句use XXX这里,包含这句,也一并删除),因为创建数据库的语句我们要自己组装。

创建数据库需要知道数据库文件和日志的存放位置(强迫用户指定貌似不太礼貌,最好自动获取到),数据库和日志文件初始大小,数据库名和排序规则。

取数据库文件和日志存放位置的办法:(我这里是把第一个库文件的位置当做默认存放位置的)

ADOQuery查询master库:        SELECT TOP 1 filename FROM sysaltfiles

然后存放默认位置就是IncludeTrailingPathDelimiter(ExtractFilePath(Trim(FieldByName('filename').AsString)))

创建数据库(仍然是在master库里执行):

        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分别是数据库文件和日志文件的初始大小,单位MB。Chinese_PRC_CI_AS为默认排序规则

需要注意的是,如果库正在被使用,DROP会出错。貌似用SQLDMO可以杀掉连那个库的进程,可以用这个野蛮残忍的办法停止对库的使用。。。

修改SQL,创建数据库结构

以下需要在刚创建的数据库中执行

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结尾加')
              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

这里注意存储过程中经常出现SET,所以不能让SET做为判断'CREATE PROCEDURE 结束的标志,而要用

SET QUOTED_IDENTIFIER OFF,只要是企业管理器导出的创建存储过程语句,必定以SET QUOTED_IDENTIFIER OFF紧跟着创建语句

        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 结尾加')
              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),可以执行Query了

 

不过我觉得SQLDMO应该有直接执行SQL语句的功能,就是支持GO和注释等的Transact-SQL,时间关系,没去深入研究SQLDMO,我暂时只是把这玩艺拿来刷数据库列表用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值