分享两条Delphi开发经验


  最近在做“数据库切割工具”时,碰到了一些辣手的问题, 通过多方打探、搜索,最终得以解决,现总结下来,给大家共享,免的大家以后在碰到 类似问题时再 消费大量 工夫去搜索、去打探!

  1、推断输入的路径在服务器上是不是存在:

  例如,要在客户端执行一个 缔造数据库的程序,数据库要在服务器上 缔造,但路径 可以手工输入,这时就面临一个推断自已现在输入的路径在服务器上是不是存在的问题, 免得在执行Create Database SQL时才报错:找不到路径 。

  具体 步骤如下:

  exec master..xp_cmdshell 'dir E:\DATA' ,在 查问 综合器中执行此段SQL,假如存在此路径,会输出此路径下的全部文件与文件夹信息,还有此盘的可用字节数与已此文件夹的字节数(图1所示);假如此路径不存在,则输出信息如图2所示, 揭示“找不到文件” 。

  然而,当路径中含有空格时,如C:\Program Files,直接用exec master..xp_cmdshell 'dir C:\Program Files',系统返回 后果会如跟图2显示一样,我们需要做额外 解决, 威力得到正确的返回 后果:

  (1)exec master..xp_cmdshell 'dir "C:\Program Files\Microsoft SQL Server\MSSQL"'

  这种写法,在 查问 综合器中直接执行是没有问题的,也能返回正确 后果,但假如放到程序中执行:

  SQL.Add('exec master..xp_cmdshell ''dir "C:\Program Files\Microsoft SQL Server\MSSQL"''),Open时就会报错,不能执行 。

  为何呢???

  (2)我们接下来查看SQL联机协助,对XP_CMDSHELL的 形容如下:

  xp_cmdshell {'command_string'} [, no_output]

  参数

  'command_string'

  是在操作系统命令行解释器上执行的命令字符串 。command_string 的数据类型为 varchar(255) 或 nvarchar(4000),没有默许值 。command_string 不能包括一对以 上的双引号 。假如由 command_string 引用的文件路径或程序名称中有空格,则需要 使用一对引号 。假如 使用嵌入空格不容易,可考量 使用 FAT 8.3 文件名作为解决办 法 。

  no_output

  是可选参数, 示意执行给定的 command_string,但不向客户端返回任何输出 。

  协助文件 揭示我们要用一对引号将文件路径或者程序名称包起来,将整个路径包不起来不会报错,那我就将带有空格的单步路径包起来试试,看看行不行,执行 如下SQL:SQL.Add('exec master..xp_cmdshell ''dir C:\"Program Files"\"Microsoft SQL Server"\MSSQL''),这样Open时果然不报错了,看来 查问 综合器的语法 审查与我们的Query自己的语法 审查还是有 定然区别的,不能等同的 。 因此,碰到路径中带空格的状况,正确的写法还是:

  exec master..xp_cmdshell 'dir C:\"Program Files"\"Microsoft SQL Server"\MSSQL'

  这同时 注明SQL协助文件中的绿色字体 部分 command_string 不能包括一对以上的双引号 的 形容是不正确的,看来SQL Server协助文件与产品也浮现了“规格与程序不相符”的问题了,呵呵......

  2、清空数据库的日志文件

  问题的引出:我们的切割过程便是将单据数据中某个日期以往的数据先复制到新的数据库中(select ... into ...), 而后再将原来数据库中的这些数据删除,这样操作在数量量很大的数据库上时,其日志文件的增进也是惊人的:我复制一个48万条记录的表时,最终发现仅这一个表的操作就使新数据库的日志文件添加了170MB,假如不加清理,那就会被日志文件占用大量珍贵的磁盘空间 。况且,我们转移到的新建数据库的作用也只不过用来 查问,以后不会有任何Insert、Update、Delete操作的,要这些日志文件没有什么 用处, 因此必须在向它转移数据的过程中做一些缩短日志文件的 解决,怎么办??问题由此而生...

  (1) 解决过程中不记录日志

  设置 步骤如下:企业治理器中 打开对应数据库的“属性”,页框“选项”中将“模型”改为“ 容易” 。这样设置的 后果是对此数据库的任何操作都将不记录事务日志 。对应的SQL为:EXEC sp_dboption @pdbName, 'trunc. log on chkpt.', 'TRUE'

  然而,我们 通过测试发现:启用此 性能后,我们在对这个数据库操作时,就不能用事务操作了,程序执行到BeginTranSaction时就报错,不能执行下去,因为我们不能在对此库的操作中 保障100%的正确性, 因此我们还需要事务, 因此这种 步骤 实用空间有限,也不能满足我们程序的需要 。

  我们还得 接续搜索.....

  (2) 解决过程中同意记录日志,但要对日志文件进行 解决,时时缩短它 。

  SQL Server的联机协助告诉我们:

  在下列状况下,日志文件的物理大小将削减:

  执行 DBCC SHRINKDATABASE 语句时 。

  执行 引用日志文件的 DBCC SHRINKFILE 语句时 。

  自动收缩操作 产生时 。

  下面我们一一 综合这三个 方案:

  ① DBCC SHRINKDATABASE:收缩特定数据库的全部数据和日志文件,包括我们的需要,但也大于我们的需要,此 方案可用,但不要 焦急,给人的觉得是买了一件能穿的衣服,但尺寸大了些,穿在身上有点不舒畅,我们接着 综合以下两个 方案...

  ② DBCC SHRINKFILE: 收缩 有关数据库的指定数据文件或日志文件大小 。与 方案1的区别仅一字之差:“和”与“或”,相当于把 方案1拆成两步来执行,我们需要的便是收缩日志文件, 因此,它对我们来说显得 比较 合适,有点 就地取材的觉得 。但还有没有更好的呢,我们来看第三个 方案...

  ③自动收缩:数据库也可设置为按给定的 工夫 间隔自动收缩,服务器定期 审查每个数据库中的空间 使用状况 。假如发现数据库中有大量闲置空间,并且它的 autoshrink 选项设置为 true,SQL Server 就缩短该数据库中的文件大小 。它是周期性的执行DBCC SHRINKDATABASE,既然 方案1已经是一件尺寸大了一些的衣服,则此 方案就相当于又穿上了N件大尺寸衣服,一件就已经够了,我还要那么多干嘛呢??

  综合对照发现, 方案2正是我们需要的 。

  DBCC SHRINKFILE ('+Trim(edDBMC.Text)+'_Log, TRUNCATEONLY)

   通过这个语句 解决以后,日志文件将回到它的最小状态504KB,任何的日志记录都将清空 。

  再 联合我们的工具,复制完一个表之后,我们就执行 方案2, 解决过程中日志文件临时占用的最大空间也便是 解决最大数据表时产生的日志空间,但最终都将清空,显示为500多KB, 有关于 宏大的数据文件而言,微之戡微.