数据库操作(转载)

只要将局的数目比较做生所必不可少的血流,那么数据库的计划虽是利用被极度关键之同片。有关数据
仓库设计之资料汗牛充栋,大学学位课程里为发生特别的叙说。不过,就如我辈反复强调的那样,再好的
先生呢比不过经验的教诲。所以我最近摸索了若干针对数据库设计好有功力的专业人士给大家传授一些使
计量数据库的技能与经验。我从接受的130 独报告中选择了内部的60
个顶尖技巧,并将这些
技术编写成了本文,为了方便索引其内容分也5 个组成部分:
第1 部分— 设计数据库之前
眼看无异有的罗列了12 个着力技巧,包括取名规范以及显而易见作业需要等。
第2 部分— 设计数据库表
总共24 个指南性技巧,涵盖表内字段设计以及该避免的广泛问题相当。
第3 部分— 选择键
怎么取舍择键呢?这里发生10
独技术专门提到系统生成的主键的对用法,还发生何时以及怎样寻找引字段
以获得最佳性能等。
第4 部分— 保证数据完整性
座谈什么保持数据库的清晰和健康,如何将危害数据回落至绝小程度。
第5 部分— 各种小技巧
非包括于以上4

只片被的其他技术,五花八门,有矣它们要您的数据库开发工作会重新轻松局部。   

第1 部分— 设计数据库之前

  1. 察现有条件
    每当设计一个初数据库时,你不光应当密切研究业务需求又还要考察现有的体系。大多数数据库项目还无是始于开始成立之;通常,机构内到底会设有用来满足一定需求的依存系统(可能没有兑现活动计算)。显然,现有系统并无圆满,否则你就不要再起新系了。但是对原来体系的钻好给你意识有些也许会见忽略的轻问题。一般的话,考察现有系统针对您绝对有便宜。

本人曾经接手了一个啊地面运输公司付出的数据库项目,活不麻烦,用之凡Access
数据库。我设置了部分项目设计参数,而且同客户共同对这些参数进行了评估,事先还翻了开发环境下所动的行事模式,等到最后安排下之时段,只见终端上出了几乎个提醒符然后立马在自面前翘辫子了!抓耳挠腮的折磨了少数只钟头,我才发觉及,原来这家店铺的纱及跑在些许个数据库应用,而针对网络的走访需要鲜明和从严的用户帐号及其访问权限。明白了就一点,问题解决:只待采取客户之网即可。这个类别被自己的训诫就是:记住,假如你于诸如Access
或者Interbase
这类公共环境下开应用程序,一定要于表下手深入系统内做明白而面临的条件到底是怎么回事。

  1. 概念标准的靶子命名规范
    定要是定义数据库对象的命名规范。对数据库表来说,从品种同样开始就要确定表名是行使复数还是单数形式。此外还要给表的别名定义简单规则(比方说,如果表名是一个单词,别叫就是获得才词之面前4
    个假名;如果表名是鲜单单词,就各取两单单词的前面片只假名组成4
    独字母长的别名;如果表底名由3
    个单词组成,你不妨起来两单单词遭各取一个然后从最终一个单词遭重复取出两独字母,结果还是整合4
    字母长的别名,其余依次类推)对工作用表来说,表名可以长前缀WORK_
    后面附上采用该表的应用程序的名。表内的列要针对键采用一整套统筹规则。比如,如果键是数字型,你可以为此_NO
    作为后缀;如果是字符类型则可以_CODE
    后缀。对列名应该下标准的前缀和后缀。再使,假如你的表里有那么些“money”字段,你不妨吃每个列长一个_AMT
    后缀。还有,日期列最好坐DATE_用作名字打头。

检查表名、报表名和查询名之间的命名规范。你可能会见快便让这些不同之数据库要素的称号为糊涂了。假如你坚持合并地命名这些数据库的不等部分,至少你该在这些目标名字的起用table、query
或者report 等前缀加以区分。

苟使用了Microsoft Access,你得用qry、rpt、tbl 和mod
等标志来标识对象(比如
tbl_Employees)。我以跟SQL Server(或者Oracle)打交道的时候还为此过tbl
来索引表,但自我于是sp_company
(现在用sp_feft_)标识存储过程,因为以一些时候如果自己发觉了双重好之处理办法往往会保留好几独拷贝。我当落实SQL
Server 2000 时用udf_ (或者类似的标志)标识我修的函数。

  1. 预先计划
    上个世纪80 年代初,我还于利用基金帐目系统及System 38
    平台,那时自己背规划有着的日子字段,这样于不花费啊力气的状况下将来就算足以轻松处理2000
    年问题了。许多人数吃本人说就算变化错过化解当下同一问题了,因为若处理起来无比辛苦了(这在世人皆知的Y2K
    问题之前那个长远了)。我回击说而预先计划今后就不见面逢好累。结果我单所以了个别周的光阴哪怕拿程序全部改动了了。因为预先计划的好,后来Y2K
    问题针对性该网的祸降到了低于水平(最近听说该次还到了1995
    年都还运行在AS/400
    系统上,唯一出现的微问题是从代码中去注释费了点工夫)。

  2. 获取数据模式资源手册
    凑巧于营示例模式的食指方可阅读《数据模式资源手册》一挥毫,该书由Len
    Silverston、W. H.Inmon 和Kent Graziano
    编写,是同按部就班值得所有的超级数据建模图书。该书概括的章涵盖多种数码领域,比如人口、机构和办事力量等。

  3. 畅想未来,但不得忘了千古之训
    自家意识询问用户如何看待未来要求变化甚有效。这样做可以高达少单目的:首先,你可解地询问下设计以谁地方该再有灵活性和哪些避免性能瓶颈;其次,你知道出事先没有规定的求变动时用户以同您同一感到吃惊。

得要记住过去的经验教训!我们开发人员还应当通过分享温馨之回味与阅历互相帮助。即使用户认为她们再为非需什么支撑了,我们呢理应针对他们进行及时方面的教导,我们都曾经面临过如此的天天“当初使是这么做了拖欠多好⋯⋯”。

  1. 每当大体实践之前开展逻辑设计
    当深切物理设计之前要事先进行逻辑设计。随着大气的CASE
    工具不断涌现出来,你的筹划也可上一定高之逻辑水准,你日常可以从完整达标重复好地问询数据库设计所欲的尽。

  2. 打听您的政工
    以你百分百地确定系自客户角度满足其需要前毫无以公的ER(实体关系)模式遭遇投入哪怕一个数据表(怎么,你还未曾模式?那请而参看技巧9)。了解你的商号工作可以以随后的开发阶段节约大量之日。一旦而肯定了作业需要,你就得好做出过多表决了。

一旦而觉得你都明朗了事情内容,你最好和客户开展相同糟糕系统的交流。采用客户之术语并且朝他们说你所想到的同而所听到的。同时还应当为此或、将见面跟要等词汇表达出体系的干基数。这样你不怕足以吃您的客户纠正你协调的了解然后开好下一样步之ER
设计。

  1. 创数量字典和ER 图表
    肯定要是花点时间创造ER
    图表和多少字典。其中至少应包含每个字段的数据类型和在每个表内的预兆外键。创建ER
    图表和数目字典确实有硌困难但针对另开发人员要询问任何规划也是完全必要的。越早创建越能够推动避免以后面临的可能混乱,从而得以吃其他问询数据库的人口犹显然哪些从数据库中取得数量。

发生相同客诸如ER
图表等新式文档其重点如何强调都未过分,这对准表明表中涉及十分有因此,而数据字典则印证了每个字段的用途及其他可能是的号。对SQL
表达式的文档化来说就是完全必要的。

  1. 缔造模式
    平摆设图纸胜了千言万语:开发人员不仅要读和贯彻其,而且还要用它们来拉协调及用户对话。模式推动增强合作效能,这样在预先的数据库设计中几乎无容许出现特别之问题。模式不必抓的百般复杂;甚至可以省略到手写在同摆放纸上就是可以了。只是要确保其及之逻辑关系今后亦可生出效果。

  2. 起输入输出下手
    于定义数据库表和字段需求(输入)时,首先应反省现有的要就筹划来之报表、查询以及视图(输出)以决定为支持这些输出哪些是必需之申及字段。举个简单的例证:假如客户需要一个表按照邮政编码排序、分段和求和,你如果保证内部囊括了独自的邮政编码字段而不用将邮政编码糅进地址字段里。

  3. 表技巧
    比方询问用户一般是什么样告数据的:批处理或者在线提交报表?时间距离是每天、每周、每月、每个季度或者年年?如果需要的话还可设想创建总结表。系统生成的主键在表中生麻烦管理。用户在富有系统生成主键的表内用副键进行搜往往会回许多再次数据。这样的追寻性能于低而便于逗混乱。

  4. 亮客户要求
    关押起就该是鲜明的行,但求就是来源于客户(这里而于中间与标客户的角度考虑)。不要因用户写下来的需求,真正的要求在客户的头里。你而于客户说其急需,而且趁机开发的累,还要时不时询问客户保证其需求仍然在付出的目的中。一个非变换的真谛是:“只有我看见了自家才清楚自己怀念只要的凡啊”必然会导致大气底返工,因为数据库没有达到客户从没写下来的需求标准。而更糟糕的凡你针对他们要求的解释只有属您协调,而且或许是截然错误的。


第2 部分— 设计表和字段

  1. 检查各种变动
    我当计划数据库的时节会考虑到怎么数据字段将来也许会见出变动。比方说,姓氏就是这么(注
    全是西方人的姓,比如女性结婚后从夫姓等)。所以,在确立体系存储客户信息经常,我倾向被
    在单独的一个数表里存储姓氏字段,而且还增大起始日及终止日等字段,这样就是好跟这等同
    数据条目的别。

  2. 采取闹含义之字段名
    出同等扭曲自家参加开发过一个种,其中起打外程序员那里继承的顺序,那个程序员喜欢用屏幕上
    显示数据指示用语命名字段,这为可以,但不幸之凡,她还爱好用有出乎意料之命名法,其命名采
    所以了匈牙利命名暨操纵序号的成形式,比如cbo1、txt2、txt2_b 等等。
    只有您以运用只面向而的缩写字段名的系,否则要尽可能地管字段描述的明白些。当然,也别
    做过头了,比如Customer_Shipping_Address_Street_Line_1 I
    虽然老具有说明性,但尚无人甘愿
    键入这么长之名字,具体标准就在您的把着。

  3. 以前缀命名
    若多个表里有不少同类型的字段(比如FirstName),你不妨用特定表的前缀(比如
    CusLastName)来救助您标识字段。

时效性数据应包括“最近更新日期/时间”字段。时间标记对找数据问题的原故、按日期再次处
理/重载数据以及消除旧数据特别有因此。

  1. 规则以及数目驱动
    多少的标准化不仅有益了好而为造福了其他人。比方说,假如你的用户界面要拜访外部数据
    发源(文件、XML
    文档、其他数据库等),你不妨将相应的连接和路信息囤积在用户界面支持表
    里。还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态相当),那
    也产生工作流的数量吧得存放于数据库里。预先安排总用付出努力,但一旦这些经过用数
    据驱动而非硬编码的法子,那么策略改变和护卫还见面便宜得几近。事实上,如果经过是数额令
    的,你不怕可以将相当可怜的义务推给用户,由用户来维护自己之工作流过程。

  2. 原则不可知过头
    针对那些未熟悉标准化一乐章(normalization
    )的总人口而言,标准化可以确保表内的字段都是最为基础的
    要素,而当时同一方推消除数据库中的数额冗余。标准化来一些栽形式,但Third
    Normal
    Form(3NF)通常为看在性、扩展性和数据完整性方面上了最好平衡。简单的话,3NF

    定:

· 表内之各级一个值都只能被发表相同浅。
· 表内之各一行还该给唯一的标识(有唯一键)。
· 表内无应储存依赖让其他键的非键信息。
遵守3NF
正规的数据库有以下特点:有雷同组表专门存放通过键连接起来的关系数据。比方说,
某某存放客户及其有关定单的3NF 数据库就可能发生个别单说明:Customer
和Order。Order 表不保证
含定单关联客户之任何音讯,但表内会存放一个键值,该键指向Customer
表里噙该客户信息
的那么一行。
再次强层次的极也时有发生,但还规范是否就必然还好吧?答案是无肯定。事实上,对某些种类来
说,甚至就连3NF 还可能被数据库引入太胜的扑朔迷离。

以效率的由,对发明不开展规范有时也是少不了的,这样的事例很多。曾经有个出财务分析
软件的生活就是是因此不标准化表把询问时自平均40
秒降低到了零星秒左右。虽然本人只好如此做,
而是自身毫不将数据表的非标准化当作理所当然的统筹意见。而具体的操作而大凡千篇一律种植派生。所以一旦表
有了问题再生不标准化的表是完全可能的。

  1. Microsoft Access 报表技巧
    如您正在使Microsoft
    Access,你得据此对用户自己的字段名来代替编号的称呼:比如用
    Customer Name
    代替txtCNaM。这样,当您用引导程序创建表单和表格时,其名会受那些休
    举凡程序员的人头重新易看。

  2. 匪活跃或不动的指示符
    加一个字段表示所当笔录是否在业务受到不再活跃挺有因此底。不管是客户、员工或其它什么
    人数,这样做且能推动重新运行查询的时过滤活跃或无欢状态。同时还破了新用户以使用
    数量常常所面临的有些问题,比如,某些记录或不再为她们所用,再去的早晚可以由至自然的
    严防作用。

  3. 动用角色实体定义属于有型的排列
    每当急需对属特定类型或者持有特定角色的事物做定义时,可以就此角色实体来创造特定的流年拉
    联关系,从而可以实现自文档化。
    这边的意义不是于PERSON 实体带有Title 字段,而是说,为什么不要PERSON
    实体和
    PERSON_TYPE 实体来描述人员也?然后,比方说,当John Smith, Engineer
    提升为John
    Smith, Director 乃至最后爬至John Smith, CIO
    的高位,而具有你只要举行的但是是反简单只说明
    PERSON 和PERSON_TYPE
    之间涉及的键值,同时多一个日子/时间字段来理解变化是何时
    发生的。这样,你的PERSON_TYPE 表就含有了有PERSON
    的或者类型,比如Associate、
    Engineer、Director、CIO 或者CEO 等。
    还发出只代表方式尽管是转PERSON
    记录来体现新头衔的转移,不过这样一来在时间及无法跟踪
    民用所处职的切实可行日子。

  4. 使常用实体命名机构数量
    集体数量的最简易方法就是是采用常用名字,比如:PERSON、ORGANIZATION、ADDRESS

    PHONE
    等等。当你把这些常用的相似名字做起来还是创造特定的照应副实体时,你便赢得了
    温馨用底特殊版。开始之时段使用一般术语的严重性缘由在拥有的具体用户还能够针对抽象事物有
    体化。
    出了这些泛意味,你虽可以以第2 级标识被动用自己的新鲜名称,比如,PERSON
    可能是
    Employee、Spouse、Patient、Client、Customer、Vendor 或者Teacher
    等。同样的,
    ORGANIZATION 也恐怕是MyCompany、MyDepartment、Competitor、Hospital、
    Warehouse、Government 等。最后ADDRESS
    可以切切实实也Site、Location、Home、Work、
    Client、Vendor、Corporate 和FieldOffice 等。
    运一般抽象术语来标识“事物”的色好叫您于关系数据因满足工作要求地方获取巨大的灵敏
    活性,同时这样做还足以明确下降数据存储所待的冗余量。

  5. 用户来源世界各地
    每当设计用到网络或有所任何国际特性的数据库时,一定要是牢记大多数国家都生异的字段格
    庆典,比如邮政编码等,有些国家,比如新西兰就没有邮政编码一说。

  6. 数码再度用采用分立的数据表
    倘你发现自己在再度输入数据,请创建新表和新的涉及。

  7. 每个表中都应当加上的3 单有效的字段
    · dRecordCreationDate,在VB 下默认是Now(),而当SQL Server
    下默认为GETDATE()
    · sRecordCreator,在SQL Server 下默认为NOT NULL DEFAULT USER
    · nRecordVersion,记录之本标记;有助于准确验证记录受出现null
    数据或者少数据的本

  8. 本着地方及电话采用多独字段
    讲述街道地址便短短一行记录是不够的。Address_Line1、Address_Line2
    和Address_Line3 可
    以提供再老的八面玲珑。还有,电话号码和邮件地址最好有自己的数据表,其间有自己的品种
    和标记类别。

过火标准化可要是小心,这样做或会见促成性上冒出问题。虽然地点及电话表分离通常可以高达
极品状态,但是如果欲常看这类信息,或许在那父表中存放“首选”信息(比如
Customer 等)更为妥当些。非标准化以及加速访问中的降是发肯定意义的。

  1. 运多个号字段
    自家觉得好震惊,许多人数当数据库里就为name
    留一个字段。我看只有刚入门的开发人员才见面立即
    啊做,但骨子里网上这种做法十分常见。我提议应拿姓氏和名字作两单字段来处理,然后于
    查询的时候还把她们成起来。

要把这种情景易得对用户更和谐有好
数方法。我无比常用的凡在相同表中创造一个计算列,通过她好活动地连续标准化后的字段,这
种数据变动的时节她呢随后变。不过,这样做在使用建模软件时得异常灵敏才实施。总之,采用连接
字段的法门可中的隔离用户以及开发人员界面。

  1. 提防大小写混用的靶子名和特殊字符
    过去极其使自己发脾气的事务有就是是数据库里发大大小小写混用的靶子名,比如CustomerData。这同问
    题从Access 到Oracle
    数据库都有。我无欣赏下这种大小写混用的对象命名方式,结果还非
    得不手工修改名字。想想看,这种数据库/应用程序能混到应用更强有力数据库的那么同样上吧?采用全
    总统大写而且蕴藏下划符的讳拥有双重好之可读性(CUSTOMER_DATA),绝对不用当目标名之
    字符中留空格。

  2. 小心保留词
    只要保管你的配段名没有和保留词、数据库系统要常用访问方法冲突,比如,最近本身修的一个
    ODBC 连接程序里有只说明,其中就用了DESC 作为证明字段名。后果可想而知!DESC

    DESCENDING 缩写后底保留词。表里的一个SELECT
    *告知句子也会用,但本身得的也是一模一样特别堆
    不要用处的信。

  3. 保持字段名和类别的一致性
    当命名字段并也该指定数据类型的早晚自然要是确保一致性。假如字段在某表中叫做
    “agreement_number”,你就转以另外一个表里把名字改成化“ref1”。假如数据类型在一个表里
    凡是整数,那在旁一个表里可尽管转变变成字符型了。记住,你关系为止自己的生存了,其他人还要用而的反复
    据库呢。

  4. 细心挑选数字型
    于SQL 中动用smallint 和tinyint
    类型要专门小心,比如,假如你想看月销售总额,你的总额字
    段类型是smallint,那么,如果总额超过了$32,767 你便非可知展开计算操作了。

  5. 删除标记
    每当表明中蕴藏一个“删除标记”字段,这样便足以管实行号为去。在关系数据库里永不单独去
    某一样行;最好用清除数据程序同时如果过细维护索引整体性。

  6. 免采用触发器
    触发器的作用通常可以据此外方实现。在调试程序时触发器可能成干扰。假如你实在需要募
    于是触发器,你最好好集中对她文档化。

  7. 富含本机制
    提议您以数据库被引入版本控制机制来规定以被之数据库的本子。无论如何你还设贯彻即无异一旦
    求。时间相同长,用户之需求总是会改变之。最终或会见要求修改数据库结构。虽然您可以经查验
    翻开新字段或者找引来确定数据库结构的本,但自己发觉将版本信息直接存放到数据库中莫更为方
    便吗?。

  8. 于文本字段留足余量
    ID 类型的文本字段,比如客户ID
    或定单号等等都应有设置得较相似想象更可怜,因为时间未长卿
    多数就是见面以要补加额外之字符而难堪不已。比方说,假要你的客户ID 为10
    位数长。那尔该
    拿数据库表字段的长度要为12 或者13
    单字符长。这终究浪费空间吗?是产生一些,但为没有你想像的
    那么多:一个字段加长3 只字符在发1
    百万久记下,再加上一些目录的景下才可吃所有数据
    库多占据3MB
    底长空。但立刻额外占据的半空中却不用将来重构整个数据库就可以实现数据库规模
    的增进了。

  9. 列命名技巧
    咱俩发现,假如你为每个表的列名都使用统一的前缀,那么当编写SQL
    表达式的时刻会获得那个
    死的简化。这样做为着实有弱点,比如破坏了自动表连接工具的打算,后者将国有列名同一些数
    本库联系起,不过就是连这些工具有时不为连续错误嘛。举个简单的例证,假设有两单说明:
    Customer 和Order。Customer
    表的前缀是cu_,所以该表内的子段名如下:cu_name_id、
    cu_surname、cu_initials 和cu_address 等。Order
    表的前缀是or_,所以子段名是:
    or_order_id、or_cust_name_id、or_quantity 和or_description 等。
    诸如此类打数据库被选出全部多少的SQL 语句可以写成如下所示:
    Select * from Customer, Order
    Where cu_surname = “MYNAME”
    and cu_name_id = or_cust_name_id
    and or_quantity = 1;
    在没这些前缀的情状下则写成是样子:
    Select * from Customer, Order
    Where Customer.surname = “MYNAME”
    and Customer.name_id = Order.cust_name_id
    and Order.quantity = 1
    第1 单SQL 语句没丢掉键入多少字符。但如若查询涉及到5
    独说明乃至更多的排你就算亮是技能
    基本上来因此了。


第3 部分— 选择键和目录

  1. 数量采掘要预先计划
    本身所于的市场机构曾使处理8
    万基本上客联系方式,同时填写每个客户的必备数据(这绝免是略
    生活)。我从中还要确定来同样组客户作为市场目标。当自身于不过开始设计表和字段的时段,我准备不
    于主索引里增加极其多的字段以便加速数据库的周转速度。然后自己意识及特定的组查询与消息采掘
    既未可靠速度也难过。结果只好在主索引中重建而且合并了数字段。我发现产生一个指令计划相
    当第一——当自己想创立系统项目查找时怎么而运号码当主索引字段为?我可就此传真号码
    进展搜寻,但是它几乎就象系统项目一样对自家吧并无重大。采用后者作为主字段,数据库更新
    继还索引和寻找就赶快多矣。

不过操作数据仓库(ODS)和数据仓库(DW)这简单种环境下的数额索引是发异样之。在DW
环境
生,你只要考虑销售单位是哪组织销售移动的。他们并无是数据库管理员,但是他们规定表内的
键信息。这里设计人员或者数据库工作人员应该分析数据库结构从而确定来性能与科学输出之间
的特级标准。

  1. 采取系统生成的主键
    顿时无异于天接近与技术1,但自己觉得有必不可少当这边再次提醒大家。假如你连在计划数据库的时节利用
    系统生成的键作为主键,那么您实际控制了数据库的目录完整性。这样,数据库和不人工机制就
    实用地操纵了针对性存储数据被每一行的造访。
    采取系统生成键作为主键还有一个独到之处:当你有所一致的键结构时,找到逻辑缺陷很容易。

  2. 解释字段用于索引
    为分离命名字段和寓字段以支撑用户定义之报表,请考虑分解其他字段(甚至主键)为其组
    成要素以便用户可针对该展开索引。索引将加速SQL
    和表格生成器脚本的实行进度。比方说,
    自身通常以必得运用SQL LIKE 表达式的图景下创造报表,因为case number
    字段无法释疑为
    year、serial number、case type 和defendant code
    等要素。性能为会转移死。假如年度以及类型字
    段可以讲为寻引字段那么这些报表运行起来便见面急忙多矣。

  3. 键设计4 原则
    · 为涉及字段创建外键。
    · 所有的键都必须唯一。
    · 避免以复合键。
    · 外键总是关联唯一的键字段。

  4. 转变忘了目录
    目录是从数据库被获取数据的尽快捷方式之一。95%底数据库性能问题还可以使用索引技术得到
    化解。作为一如既往修规则,我便对逻辑主键使用唯一的成组索引,对系统键(作为存储过程)采用
    唯一的非成组索引,对其它外键列下非成组索引。不过,索引就象是盐,太多矣菜就篌了。你
    得考虑数据库的空间发出多要命,表如何进行走访,还有这些访问是否要用作读写。

多数数据库都引得自动创建的主键字段,但是可生成忘了目录外键,它们啊是常事采取的键,比
若果运行查询显示主表和装有关联表的有条记下就是就此得上。还有,不要索引memo/note
字段,不
假若摸引大型字段(有为数不少字符),这样作会于索引占用太多的存储空间。

  1. 绝不索引常用之小型表
    不要啊微型数据表设置任何键,假如它们经常发生插入和去操作就更别这样作了。对这些插入和
    删去操作的目维护或比较扫描表空间消耗又多的日子。

  2. 毫无拿社会保障号码(SSN)选作键
    世代都毫无使SSN
    作为数据库的键。除了隐私原因之外,须知政府进一步趋于于无批准把
    SSN 用作除收入有关外的其余目的,SSN
    需要手工输入。永远不要以手工输入的键作为主
    键,因为要你输入错误,你唯一能开的就是去除所有记录然后从头开始。

上个世纪70 年代我还于朗诵大学的时候,我记得那时SSN
还就给用做学号,当然尽管这样做是休
模仿的。而且人们为都懂这是不法的,但他们就习惯了。后来,随着盗取身份犯罪案件的长
加,我今天底大学校园正痛苦地从同特别摊数据被管SSN 删除。

  1. 甭用用户的键
    以确定以什么字段作为表的键的时光,可得要小心用户即将编辑的字段。通常的景象下非使
    慎选用户可编制的字段作为键。这样做会迫使你下以下简单个法子:
    ·
    在创建记录下对用户编辑字段的一言一行施加限制。假如你如此做了,你也许会见发觉而的应用程
    程序在商务需求突然发生变化,而用户要编制那些不可编辑的字段时不够足够的灵活性。当用
    户在输入数据之后直到保存记录才意识网出了问题他们该怎么想?删除重建?假如记录不可
    重建是否让用户走起来?
    ·
    提出有检测与纠正键冲突之方式。通常,费点精力为就是做定了,但是自性能上来拘禁这么做的
    代价就是比较充分了。还有,键的改或者会见迫使你突破你的数额和商业/用户界面层之间的相间
    离。
    为此还是再次提一句古语:你的统筹要服用户一旦不是叫用户来适应你的宏图。

未为主键具有可更新性的因由是在干模式下,主键实现了不同表之间的涉。比如,
Customer 表有一个主键CustomerID,而客户之定单则存放于其他一个表里。Order
表的主键可能
凡是OrderNo 或者OrderNo、CustomerID
和日期的组成。不管你选择啊种键设置,你还得在
Order 表中存放CustomerID 来管你可以吃下定单的用户找到其定单记录。
设你于Customer 表里窜了CustomerID,那么你必寻找有Order
表中之持有有关记录对该前进
推行修改。否则,有些定单就会不属其他客户——数据库的完整性就算完蛋了。
若果找引完整性规则施加到说明一级,那么在非修大量代码和叠加删除记录之事态下几乎未容许
转有平等条记下的键和数据库内存有涉嫌的笔录。而立即同过程反复错误丛生所以应该尽量避免。

  1. 而选键有时只是做主键
    牢记,查询数据的未是机器而是丁。
    倘你生出可选键,你可能更加把它们用做主键。那样的话,你就是持有了树立强有力索引的力。这
    类可以阻止使用数据库的人不得不连续数据库从而方便的过滤数据。在严格控制域表的数据库
    达成,这种负荷是较显然的。如果只是选键真正发出因此,那就是是达标了主键的档次。
    自家之眼光是,假如你来可选键,比如国家表内的state_code,你不要以存活不能够改的绝无仅有键直达
    创后续之键。你只要做的特是开创毫无价值的数量。比如以下的例子:
    Select count(*)
    from address, state_ref
    where
    address.state_id = state_ref.state_id
    and state_ref.state_code = ‘TN’
    自身的做法是如此的:
    Select count(*)
    from address
    where
    and state_code = ‘TN’
    假使你因过度使用表的后续键建立这种表底涉嫌,操作负载真得用考虑一下了。

  2. 变动忘了外键
    大部数据库索引自动创建的主键字段。但转变忘了目录外键字段,它们当您想查询主表中之笔录
    连同涉及记录时老是都见面用到。还有,不要索引memo/notes
    字段而且不要索引大型文本字段
    (许多字符),这样做会叫您的目占据大量底数据库空间。         


第4 部分— 保证数据的完整性

  1. 为此约束若非商务规则强制数据完整性
    如果你本商务规则来处理需,那么您应有检查商务层次/用户界面:如果商务规则后产生转移
    成,那么就需要展开创新即可。
    假设需求来维护数据完整性的用,那么以数据库层面上得施加限制标准。
    要是您以数据层确实下了约,你如果保证有法子将创新不能够经过自律检查的由使用户了解
    的语言通知用户界面。除非你的字段命名很冗长,否则字段名本身还不够。

设发生或,请以数据库系统实现数据的完整性。这不仅仅包括经标准实现的完整性而且还
包括数据的功能性。在描绘多少的时节还足以长触发器来保证数据的科学。不要因让商务层
保证数据完整性;它不能够保证表之间(外键)的完整性所以无克强加于外完整性规则之上。

  1. 分布式数据系统
    对分布式系统而言,在您说了算是否以相继站点复制所有数据或者把数量保存于一个地方之前应
    估计一下前景5 年要么10
    年的数据量。当您管多少传送到任何站点的时光,最好以数据库字段
    惨遭装置有标志。在目的站点收到你的多寡后更新您的号。为了拓展这种多少传,请写下
    乃协调的批判处理还是调度程序因一定时刻间隔运行而毫无为用户在每日的行事晚传输数据。本地
    拷贝你的保安数据,比如计算常数和利等,设置版本号保证数据在每个站点都完全一致。

  2. 强制指示完整性
    不曾好点子能以伤数据上数据库后排其,所以若当于她上数据库之前以其删除。激
    活着数据库系统的指令完整性特性。这样可保持数据的干净而能够迫使开发人员投入还多的时间处
    调理错误条件。

  3. 关系
    若是少单实体之间在多对同提到,而且还有可能转向为多针对性大多涉及,那么您最好同一初步就是设置
    成为多对大多涉及。从现有的基本上对同样干变化也多针对几近干比较平始发即是差不多对准多关系而麻烦得差不多。

  4. 应用视图
    为在您的数据库与汝的应用程序代码之间提供其他一样交汇抽象,你可以吗汝的应用程序建立专门的
    视图而不用非要是应用程序直接访问数据表。这样做还相当于在处理数据库变更时被你提供了重多之
    自由。

  5. 被多少具有和回复制定计划
    考虑数据颇具策略并包含在设计过程中,预先设计而的数据恢复过程。采用可以发表于用户/开发
    人口的数量字典实现好之数识别而确保对数码源文档化。编写在线更新来“更新查询”供
    以后万同数量丢失可重新处理更新。

  6. 故而存储过程叫系统做重活
    缓解了累累累来来一个装有高度完整性的数据库解决方案后,我所当的团组织决定封装一些
    关联表的功能组,提供一整套正规的囤积过程来做客各组以便加快速度和简化客户程序代码的起来
    发。在此期间,我们发现3GL
    编码器设置了富有或的不当条件,比如以下所示:
    SELECT Cnt = COUNT (*)
    FROM [

<>]
WHERE [ ] =
IF Cnt = 0
BEGIN
INSERT INTO [ >

<>]
( [< primary key column>] )
VALUES ( )
END
ELSE
BEGIN

END
设若一个非3GL 编码器是如此做的:
INSERT INTO [ >

<>]
( [< primary key column>] )
VALUES
( )
IF @@ERROR = 2627 — Literal error code for Primary Key Constraint
BEGIN

END
第2
个程序简单多了,而且实际,利用了咱叫数据库的机能。虽然我个人无欣赏以嵌入文
配(2627)。但是那样可以好有益于地用某些预处理来代替。数据库不仅是一个存放数据的地
正,它呢是简化编码之地。

  1. 运用查找
    控制数据完整性的最佳艺术尽管是限量用户之挑三拣四。只要出或还应该提供被用户一个清的价
    列表供其择。这样以削减键入代码的不当与误解而提供数据的一致性。某些公共数据特别正
    一齐查找:国家代码、状态代码等。

第5 部分— 各种小技巧

  1. 文档、文档、文档
    针对拥有的快捷方式、命名规范、限制与函数都设编文档。

动用让表、列、触发器等加注的数据库工具。是的,这起硌费事,但从长久来拘禁,这样做对起来
犯、支持与跟修改好实用。

有赖于你利用的数据库系统,可能有局部软件会于您有些供你速上手的文档。你或要先开
起来在游说,然后抱越来越多之底细。或者你或许想周期性的预排,在输入新数据同时随着你的
拓展对各级一样片细节化。不管你挑选啊种方式,总要对准君的数据库文档化,或者以数据库自身的
里面或独立建立文档。这样,当您了了扳平年多时间后还回过头来做第2
只本子,你犯错的时
拿大大减少。

  1. 行使常用英语(或者其它任何语言)而不用采取编码
    干什么我们经常应用编码(比如9935A 可能是墨水笔的供代码,4XF788-Q
    可能是帐目编
    堆)?理由很多。但是用户一般还为此英语进行考虑要无是编码。工作5
    年的出纳员或许知道
    4XF788-Q
    是呀事物,但新来之不过即不自然了。在创建下拉菜单、列表、报表时不过好以英语
    名排序。假如你需要编码,那你可在编码旁沾满用户知道之英语。

  2. 封存常用信息
    深受一个表专门存放一般数据库信息非常管用。我不时于这表里存放数据库时版、最近检讨/修
    更(对Access)、关联设计文档的称呼、客户等信息。这样可兑现均等种植简单机制跟踪数据
    库房,当客户抱怨他们的数据库没有达标梦想之要求如同你联系时,这样做对非客户机/服务器环境
    专程有因此。

  3. 测试、测试、反复测试
    树立或者修订数据库后,必须用用户新输入的数据测试数据字段。最要的是,让用户展开测量
    试行并且与用户一起保险你挑选的数据类型满足商业要求。测试用以将新数据库投入实际服务的
    前完成。

  4. 反省计划
    以出中检查数据库设计的常用技术是通过该所支撑之应用程序原型检查数据库。换句话说,
    针对各个一样种植最终表达数据的原型应用,保证你检查了数据模型并且查看如何取出数据。

  5. Access 设计技术
    本着复杂的Microsoft Access
    数据库应用程序而言,可以将具备的主表放在一个数据库文件里,然
    晚增加其它数据库文件和装同旧数据库有关的奇异函数。根据需要用这些函数连接到主文件
    着之主表。比如数据输入、数据QC、统计分析、向管理层要政府部门提供报表和各只读
    询问等。这同一计简化了用户和组权限的分配,而且好应用程序函数的分组和细分,从而以
    次第必须修改的下容易管理。

14:32 | 评论
(0)

MS
SQL数据库备份和还原存储过程

if exists(
select * from sysobjects
where name=””””pr_backup_db”””” and xtype=””””p””””
)
begin
drop proc pr_backup_db
end

go

/*备份数据库*/
create proc pr_backup_db
@flag varchar(10) out,
@backup_db_name varchar(128),
@filename varchar(1000) –路径+文件名字
as
declare @sql nvarchar(4000),@par nvarchar(1000)
select @par=””””@filename varchar(1000)””””
select @sql=””””BACKUP DATABASE ””””+@backup_db_name+””””
to disk=@filename with init””””
execute sp_executesql @sql,@par,@filename
select @flag=””””ok””””
go

if exists(
select * from sysobjects
where name=””””fn_GetFilePath”””” and
xtype=””””fn””””
)
begin
drop function fn_GetFilePath
end
go

/*创立函数,得到文件得路径*/
create function fn_GetFilePath(@filename nvarchar(260))
returns nvarchar(260)
as
begin
declare @file_path nvarchar(260)
declare @filename_reverse nvarchar(260)
select @filename_reverse=reverse(@filename)
select
@file_path=substring(@filename,1,len(@filename)+1-charindex(””””\””””,@filename_reverse))
return @file_path
end

go

if exists(
select * from sysobjects
where name=””””pr_restore_db”””” and xtype=””””p””””
)
begin
drop proc pr_restore_db
end
go

create proc pr_restore_db /*卷土重来数据库*/
@flag varchar(20) out, /*经过运行的状态标志,是输入参数*/
@restore_db_name nvarchar(128), /*设若恢复的数码名字*/
@filename nvarchar(260) /*备份文件存放的门径+备份文件名字*/
as
declare @proc_result tinyint
/*回到系统存储过程xp_cmdshell运行结果*/
declare @loop_time smallint /*循环次数*/
declare @max_ids smallint /*@tem表的ids列最充分屡屡*/
declare @file_bak_path nvarchar(260) /*本来数据库存放路径*/
declare @flag_file bit /*文本存放标志*/
declare @master_path nvarchar(260) /*数据库master文件路径*/
declare @sql nvarchar(4000),@par nvarchar(1000)
declare @sql_sub nvarchar(4000)
declare @sql_cmd nvarchar(4000)
/*
认清参数@filename文件格式合法性,以备用户输入类似d: 或者 c:\a\
等不法文件称
参数@filename里面要来””””\””””并且不以””””\””””结尾
*/
if right(@filename,1)<>””””\”””” and
charindex(””””\””””,@filename)<>0
begin
select @sql_cmd=””””dir ””””+@filename
EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
IF (@proc_result<>0)
/*系存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
begin
select @flag=””””not exist”””” /*备份文件不存在*/
return /*退过程*/
end
/*开创临时表,保存由备份集内包含的数据库及日志文件列表组成的结果集*/
create table #tem(
LogicalName nvarchar(128), /*文件之逻辑名称*/
PhysicalName nvarchar(260) , /*文件的物理名称或操作系统名称*/
Type char(1), /*数据文件 (D) 或日志文件 (L)*/
FileGroupName nvarchar(128), /*涵盖文件之文书组称*/
[Size] numeric(20,0), /*即大小(以字节为单位)*/
[MaxSize] numeric(20,0) /*许的不过要命尺寸(以字节为单位)*/
)
/*
缔造表变量,表结构及临时表基本一致
即使是多了片列,
列ids(自增编号列),
列file_path,存放文件的门道
*/
declare @tem table(
ids smallint identity, /*自从增编号列*/
LogicalName nvarchar(128),
PhysicalName nvarchar(260),
File_path nvarchar(260),
Type char(1),
FileGroupName nvarchar(128)
)
insert into #tem
execute(””””restore filelistonly from
disk=””””””””””””+@filename+””””””””””””””””)
/*拿临时表导入表变量中,并且计算产生相应得路径*/
insert into
@tem(LogicalName,PhysicalName,File_path,Type,FileGroupName)
select
LogicalName,PhysicalName,dbo.fn_GetFilePath(PhysicalName),Type,FileGroupName
from #tem
if @@rowcount>0
begin
drop table #tem
end
select @loop_time=1
select @max_ids=max(ids) /*@tem表的ids列最可怜勤*/
from @tem
while @loop_time<=@max_ids
begin
select @file_bak_path=file_path
from @tem where ids=@loop_time
select @sql_cmd=””””dir ””””+@file_bak_path
EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
/*网存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
IF (@proc_result<>0)
select @loop_time=@loop_time+1
else
BREAK /*从未找到备份前数据文件原有存放路径,退出循环*/
end
select @master_path=””””””””
if @loop_time>@max_ids
select @flag_file=1 /*备份前数据文件原有存放路径有*/
else
begin
select @flag_file=0 /*备份前数据文件原有存放路径不有*/
select @master_path=dbo.fn_GetFilePath(filename)
from master..sysdatabases where name=””””master””””
end
select @sql_sub=””””””””
/*type=””””d””””是数据文件,type=””””l””””是日记文件
*/
/*@flag_file=1时初的数据库文件要存放于原本路线,否则存放路径和master数据库路径一样*/
select @sql_sub=@sql_sub+””””move
””””””””””””+LogicalName+”””””””””””” to
””””””””””””
+case type
when ””””d”””” then case @flag_file
when 1 then File_path
else @master_path
end
when ””””l”””” then case @flag_file
when 1 then File_path
else @master_path
end
end
+case type
when ””””d”””” then
@restore_db_name+””””_””””+LogicalName+””””_data.mdf””””””””,””””
when ””””l”””” then
@restore_db_name+””””_””””+LogicalName+””””_log.ldf””””””””,””””
end
from @tem
select @sql=””””RESTORE DATABASE @db_name FROM DISK=@filename with
””””
select @sql=@sql+@sql_sub+””””replace””””
select @par=””””@db_name nvarchar(128),@filename
nvarchar(260)””””
print @sql
execute sp_executesql
@sql,@par,@db_name=@restore_db_name,@filename=@filename
select @flag=””””ok”””” /*操作成*/
end
else
begin
SELECT @flag=””””file type error””””
/*参数@filename输入格式错误*/
end

–备份数据库test_database
declare @fl varchar(10)
execute pr_backup_db @fl
out,””””test_database””””,””””c:\test_database.bak””””
select @fl

–恢复数据库,输入的参数错误
declare @fl varchar(20)
exec pr_restore_db @fl out,””””sa””””,””””c:\””””
select @fl

–恢复数据库,即创造数据库test_database的复本test_db
declare @fl varchar(20)
exec pr_restore_db @fl
out,””””test_db””””,””””c:\test_database.bak””””
select @fl

面写了MS SQL数据库备份和恢复存储过程

起感觉功能不太齐全,就再度勾了扳平提高版本,经过测试成功!
先用代码发布出来,大家共享。
假如发觉察BUG,请大家指教或EMAIL:aierong@vip.sina.com

/**//*备份数据库*/
create proc pr_backup_db
@flag varchar(20) out,
@backup_db_name varchar(128),
@filename varchar(1000)  –路径+文件名字
as
declare @sql nvarchar(4000),@par nvarchar(1000)
if not exists(
select * from master..sysdatabases
  where name=@backup_db_name
  )
begin
select @flag=””””db not exist””””  /**//*数据库不存*/
return
end
else
begin
if right(@filename,1)<>”””””””” and
charindex(””””””””,@filename)<>0
begin
  select @par=””””@filename varchar(1000)””””
  select @sql=””””BACKUP DATABASE ””””+@backup_db_name
                         +”””” to disk=@filename with init””””
  execute sp_executesql @sql,@par,@filename
  select @flag=””””ok””””
  return
end
else
begin
  select @flag=””””file type
error””””  /**//*参数@filename输入格式错误*/
  return
end
end

GO

/**//*始建函数,得到文件得路径*/
create function fn_GetFilePath(@filename nvarchar(260))
returns nvarchar(260)   
as
begin
declare @file_path nvarchar(260)
declare @filename_reverse nvarchar(260)
select @filename_reverse=reverse(@filename)
select
@file_path=substring(@filename,1,len(@filename)+1-charindex(””””””””,@filename_reverse))
return @file_path
end

GO

/**//*光复数据库*/
CREATE  proc pr_restore_db    

/**//*

Create Time:    2004-03-20
Update Time:    2004-03-29 11:05
Author:         aierong
Remark:         恢复数据库

  

*/
/**//*进程运行的状态标志,是输入参数*/      
@flag varchar(20) out,    
/**//*若东山再起的数额名字*/
@restore_db_name nvarchar(128),
/**//*备份文件存放的路径+备份文件名字*/
@filename nvarchar(260)         
as
/**//*返系统存储过程xp_cmdshell运行结果*/
declare @proc_result tinyint
/**//*巡回次数*/
declare @loop_time smallint  
/**//*@tem表的ids列最酷累*/
declare @max_ids smallint    
/**//*原数据库存放路径*/
declare @file_bak_path nvarchar(260)  
/**//*文本存放标志*/
declare @flag_file bit   
/**//*数据库master文件路径*/
declare @master_path nvarchar(260)  
declare @sql nvarchar(4000),@par nvarchar(1000)
declare @sql_sub nvarchar(4000)
declare @sql_cmd nvarchar(100)
declare @sql_kill nvarchar(100)
/**//*
看清参数@filename文件格式合法性,以防范用户输入类似d: 或者 c:a
等地下文件称
参数@filename里面要发””””””””并且不盖””””””””结尾
*/
if right(@filename,1)<>”””””””” and
charindex(””””””””,@filename)<>0
begin
select @sql_cmd=””””dir ””””+@filename
EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
/**//*系统存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
IF (@proc_result<>0)  
begin
  /**//*备份文件不存*/
  select @flag=””””not exist””””   
  /**//*退过程*/
  return  
end
/**//*创造临时表,保存由备份集内包含的数据库与日志文件列表组成的结果集*/
create table #tem(
     /**//*文件的逻辑名称*/
     LogicalName nvarchar(128),
     /**//*文本之大体名称或者操作系统名称*/
     PhysicalName nvarchar(260) ,
            /**//*数据文件 (D) 或日志文件 (L)*/
     Type char(1),  
     /**//*蕴含文件的文本组称*/
     FileGroupName nvarchar(128),
                          /**//*现阶段大小(以字节为单位)*/
     [Size] numeric(20,0),  
     /**//*兴的绝酷尺寸(以字节为单位)*/
     [MaxSize] numeric(20,0)  
   )
/**//*
创表变量,表结构及临时表基本一致
即便是大抵了点滴排,
列ids(自增编号列),
列file_path,存放文件之路
*/
declare @tem table(       
     /**//*打增编号列*/
     ids smallint identity,  
     LogicalName nvarchar(128),
     PhysicalName nvarchar(260),
     File_path nvarchar(260),
     Type char(1),  
     FileGroupName nvarchar(128)
   )
insert into #tem
  execute(””””restore filelistonly from
disk=””””””””””””+@filename+””””””””””””””””)
/**//*将现表导入表变量中,并且计算出相应得路径*/
insert into
@tem(LogicalName,PhysicalName,File_path,Type,FileGroupName)  
  select
LogicalName,PhysicalName,dbo.fn_GetFilePath(PhysicalName),Type,FileGroupName
   from #tem
if @@rowcount>0
begin
  drop table #tem
end
select @loop_time=1
/**//*@tem表的ids列最特别屡屡*/
select @max_ids=max(ids)  
  from @tem
while @loop_time<=@max_ids
begin
  select @file_bak_path=file_path
   from @tem where ids=@loop_time
  select @sql_cmd=””””dir ””””+@file_bak_path
  EXEC @proc_result = master..xp_cmdshell @sql_cmd,no_output
  /**//*系存储过程xp_cmdshell返回代码值:0(成功)或1(失败)*/
  IF (@proc_result<>0)
   select @loop_time=@loop_time+1  
  else
   /**//*没找到备份前数据文件原有存放路径,退出循环*/
   BREAK
end
select @master_path=””””””””
if @loop_time>@max_ids
  /**//*备份前数据文件原有存放路径是*/
  select @flag_file=1   
else
begin
  /**//*备份前数据文件原有存放路径不设有*/
  select @flag_file=0  
  select @master_path=dbo.fn_GetFilePath(filename)
   from master..sysdatabases
   where name=””””master””””
end
select @sql_sub=””””””””
/**//*type=””””d””””是数据文件,type=””””l””””是日记文件
*/
/**//*@flag_file=1时初的数据库文件或者存放于原本路线,否则存放路径和master数据库路径一样*/
select @sql_sub=@sql_sub+””””move
””””””””””””+LogicalName+”””””””””””” to
””””””””””””
   +case type
         when ””””d”””” then case @flag_file
             when 1 then  File_path
      else @master_path
          end    
         when ””””l”””” then case  @flag_file
      when 1 then  File_path
      else @master_path
          end    
   end
   +case type
    when ””””d”””” then @restore_db_name
           +””””_DATA””””
           /**//*叫文件编号*/
           +convert(sysname,ids)  
           +””””.””””
           /**//*叫文件在后缀名,mdf or ndf*/
           +right(PhysicalName,3)  
           +””””””””””””,””””  
    when ””””l”””” then @restore_db_name
           +””””_LOG””””
           /**//*让文件编号*/
           +convert(sysname,ids)   
           +””””.””””
           /**//*为文件参加后缀名,mdf or ndf*/
           +right(PhysicalName,3)  
           +””””””””””””,””””  
    end
   from @tem
select @sql=””””RESTORE DATABASE @db_name ””””
                        +””””FROM DISK=@filename with ””””
select @sql=@sql+@sql_sub+””””replace””””
select @par=””””@db_name nvarchar(128),@filename
nvarchar(260)””””
/**//*关门相关进程,把相应进程状况导入临时表中*/
select identity(int,1,1) ids, spid
  into #temp
  from master..sysprocesses
  where dbid=db_id(@restore_db_name)
/**//*找到相应进程*/
if @@rowcount>0
begin   
  select @max_ids=max(ids)
   from #temp
  select @loop_time=1
  while @loop_time<=@max_ids
  begin
   select @sql_kill=””””kill ””””+convert(nvarchar(20),spid)
    from #temp
    where ids=@loop_time
   execute sp_executesql @sql_kill
   select @loop_time=@loop_time+1
  end
end
drop table #temp
execute sp_executesql @sql,
                                      @par,
                                      @db_name=@restore_db_name,
                                      @filename=@filename
/**//*操作成*/
select @flag=””””ok””””   
end
else
begin
/**//*参数@filename输入格式错误*/
SELECT @flag=””””file type error””””  
end

GO

/*运行*/

–备份数据库test_database
declare @fl varchar(10)
execute pr_backup_db @fl
out,””””test_database””””,””””c:\test_database.bak””””
select @fl

–恢复数据库,输入的参数错误
declare @fl varchar(20)
exec pr_restore_db @fl out,””””sa””””,””””c:\””””
select @fl

–恢复数据库,即创造数据库test_database的复本test_db
declare @fl varchar(20)
exec pr_restore_db @fl
out,””””test_db””””,””””c:\test_database.bak””””
select @fl

实际可以拘留
http://dev.csdn.net/article/28/28463.shtm

14:28 | 评论
(0)

SQL语句导入导出方法

/*******  导出到excel
EXEC master..xp_cmdshell ””bcp SettleDB.dbo.shanghu out c:\temp1.xls
-c -q -S”GNETDATA/GNETDATA” -U”sa” -P””””

/***********  导入Excel
SELECT *
FROM OpenDataSource( ””Microsoft.Jet.OLEDB.4.0””,
  ””Data Source=”c:\test.xls”;User ID=Admin;Password=;Extended
properties=Excel 5.0””)…xactions

/*动态文件称
declare @fn varchar(20),@s varchar(1000)
set @fn = ””c:\test.xls””
set @s =””””””Microsoft.Jet.OLEDB.4.0””””,
””””Data Source=”””+@fn+”””;User ID=Admin;Password=;Extended
properties=Excel 5.0””””””
set @s = ””SELECT * FROM OpenDataSource
(””+@s+””)…sheet1$””
exec(@s)
*/

SELECT cast(cast(科目编号 as numeric(10,2)) as nvarchar(255))+”” ””
转换后底号
FROM OpenDataSource( ””Microsoft.Jet.OLEDB.4.0””,
  ””Data Source=”c:\test.xls”;User ID=Admin;Password=;Extended
properties=Excel 5.0””)…xactions

/********************** EXCEL导到长途SQL
insert OPENDATASOURCE(
         ””SQLOLEDB””,
         ””Data Source=远程ip;User ID=sa;Password=密码””
         ).库名.dbo.表名 (列名1,列名2)
SELECT 列名1,列名2
FROM OpenDataSource( ””Microsoft.Jet.OLEDB.4.0””,
  ””Data Source=”c:\test.xls”;User ID=Admin;Password=;Extended
properties=Excel 5.0””)…xactions

/** 导入文本文件
EXEC master..xp_cmdshell ””bcp dbname..tablename in c:\DT.txt -c
-Sservername -Usa -Ppassword””

/** 导出文件文件
EXEC master..xp_cmdshell ””bcp dbname..tablename out c:\DT.txt -c
-Sservername -Usa -Ppassword””

EXEC master..xp_cmdshell ””bcp “Select * from dbname..tablename”
queryout c:\DT.txt -c -Sservername -Usa -Ppassword””

导出到TXT文本,用逗号分开
exec master..xp_cmdshell ””bcp “库名..表名” out “d:\tt.txt” -c -t
,-U sa -P password””

BULK INSERT 库名..表名
FROM ””c:\test.txt””
WITH (
    FIELDTERMINATOR = ””;””,
    ROWTERMINATOR = ””\n””
)

–/* dBase IV文件
select * from
OPENROWSET(””MICROSOFT.JET.OLEDB.4.0””
,””dBase IV;HDR=NO;IMEX=2;DATABASE=C:\””,””select * from
[客户资料4.dbf]””)
–*/

–/* dBase III文件
select * from
OPENROWSET(””MICROSOFT.JET.OLEDB.4.0””
,””dBase III;HDR=NO;IMEX=2;DATABASE=C:\””,””select * from
[客户资料3.dbf]””)
–*/

–/* FoxPro 数据库
select * from openrowset(””MSDASQL””,
””Driver=Microsoft Visual FoxPro
Driver;SourceType=DBF;SourceDB=c:\””,
””select * from [aa.DBF]””)
–*/

/**************导入DBF文件****************/
select * from openrowset(””MSDASQL””,
””Driver=Microsoft Visual FoxPro Driver;
SourceDB=e:\VFP98\data;
SourceType=DBF””,
””select * from customer where country != “USA” order by
country””)
go
/***************** 导出到DBF
***************/
如若假定导出数据到既变化结构(即现存的)FOXPRO表中,可以直接用底的SQL语句

insert into openrowset(””MSDASQL””,
””Driver=Microsoft Visual FoxPro
Driver;SourceType=DBF;SourceDB=c:\””,
””select * from [aa.DBF]””)
select * from 表

说明:
SourceDB=c:\  指定foxpro表所于的文本夹
aa.DBF        指定foxpro表的公文名.

/*************导出到Access********************/
insert into openrowset(””Microsoft.Jet.OLEDB.4.0””,
   ””x:\A.mdb””;””admin””;””””,A表) select * from
数据库名..B表

/*************导入Access********************/
insert into B表 selet * from
openrowset(””Microsoft.Jet.OLEDB.4.0””,
   ””x:\A.mdb””;””admin””;””””,A表)

文本称也参数
declare @fname varchar(20)
set @fname = ””d:\test.mdb””
exec(””SELECT a.* FROM
opendatasource(””””Microsoft.Jet.OLEDB.4.0””””,
    ””””””+@fname+””””””;””””admin””””;””””””””,
topics) as a ””)

SELECT *
FROM OpenDataSource( ””Microsoft.Jet.OLEDB.4.0””,
  ””Data Source=”f:\northwind.mdb”;Jet OLEDB:Database
Password=123;User ID=Admin;Password=;””)…产品

*********************  导入 xml 文件

DECLARE @idoc int
DECLARE @doc varchar(1000)
–sample XML document
SET @doc =””

  
      
      Customer was very satisfied
      
   
   
      
            Important
            Happy Customer.
      
      
   

””
— Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

— Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, ””/root/Customer/Order””, 1)
      WITH (oid     char(5),
            amount  float,
            comment ntext ””text()””)
EXEC sp_xml_removedocument @idoc

???????

/**********************Excel导到Txt****************************************/
想用
select * into opendatasource(…) from opendatasource(…)
落实将一个Excel文件内容导入到一个文件文件

假设Excel中生零星列,第一名列姓名,第二名列特别行帐号(16位)
且银行帐号导出到文本文件后划分点儿局部,前8各项和晚8各项分别。

邹健:
苟只要就此而点的口舌插入的话,文本文件要存在,而且产生一行:姓名,银行账号1,银行账号2
然后便可以为此脚的说话进行插队
顾文件称和目录根据你的莫过于状况展开修改.

insert into
opendatasource(””MICROSOFT.JET.OLEDB.4.0””
,””Text;HDR=Yes;DATABASE=C:\””
)…[aa#txt]
–,aa#txt)
–*/
select 姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8)
from
opendatasource(””MICROSOFT.JET.OLEDB.4.0””
,””Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls””
–,Sheet1$)
)…[Sheet1$]

假若您想直接插入并转移文书文件,就要用bcp

declare @sql varchar(8000),@tbname varchar(50)

–首先将excel表内容导入到一个大局临时表
select @tbname=””[##temp””+cast(newid() as
varchar(40))+””]””
,@sql=””select
姓名,银行账号1=left(银行账号,8),银行账号2=right(银行账号,8)
into ””+@tbname+”” from
opendatasource(””””MICROSOFT.JET.OLEDB.4.0””””
,””””Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\a.xls””””
)…[Sheet1$]””
exec(@sql)

–然后就此bcp从大局临时表导出至文本文件
set @sql=””bcp “””+@tbname+””” out “c:\aa.txt” /S”(local)” /P””
/c””
exec master..xp_cmdshell @sql

–删除临时表
exec(””drop table ””+@tbname)

/********************传输整个数据库*********************************************/

为此bcp实现的积存过程

/*
兑现多少导入/导出的囤过程
         根据不同之参数,可以兑现导入/导出整个数据库/单个表
调用示例:
–导出调用示例
—-导出单个表
exec file2table
””zj””,””””,””””,””xzkh_sa..地方资料””,””c:\zj.txt””,1
—-导出整个数据库
exec file2table
””zj””,””””,””””,””xzkh_sa””,””C:\docman””,1

–导入调用示例
—-导入单个表
exec file2table
””zj””,””””,””””,””xzkh_sa..地面资料””,””c:\zj.txt””,0
—-导入整个数据库
exec file2table
””zj””,””””,””””,””xzkh_sa””,””C:\docman””,0

*/
if exists(select 1 from sysobjects where name=””File2Table”” and
objectproperty(id,””IsProcedure””)=1)
drop procedure File2Table
go
create procedure File2Table
@servername varchar(200)  –服务器名
,@username varchar(200)   –用户称,如果用NT验证措施,则也空””””
,@password varchar(200)   –密码
,@tbname
varchar(500)   –数据库.dbo.表名,如果非点名:.dbo.表名,则导出数据库的备用户表
,@filename
varchar(1000)  –导入/导出路径/文件称,如果@tbname参数指明是导出整个数据库,则这参数是文本存放路径,文件称机关用表名.txt
,@isout bit      –1为导出,0为导入
as
declare @sql varchar(8000)

if @tbname like ””%.%.%”” –如果指定了表名,则直导出单个表
begin
set @sql=””bcp ””+@tbname
  +case when @isout=1 then ”” out ”” else ”” in ”” end
  +”” “””+@filename+””” /w””
  +”” /S ””+@servername
  +case when isnull(@username,””””)=”””” then ”””” else ””
/U ””+@username end
  +”” /P ””+isnull(@password,””””)
exec master..xp_cmdshell @sql
end
else
begin –导出全方位数据库,定义游标,取出所有的用户表
declare @m_tbname varchar(250)
if right(@filename,1)<>””\”” set
@filename=@filename+””\””

set @m_tbname=””declare #tb cursor for select name from
””+@tbname+””..sysobjects where xtype=””””U””””””
exec(@m_tbname)
open #tb
fetch next from #tb into @m_tbname
while @@fetch_status=0
begin
  set @sql=””bcp ””+@tbname+””..””+@m_tbname
   +case when @isout=1 then ”” out ”” else ”” in ”” end
   +”” “””+@filename+@m_tbname+””.txt ” /w””
   +”” /S ””+@servername
   +case when isnull(@username,””””)=”””” then ”””” else
”” /U ””+@username end
   +”” /P ””+isnull(@password,””””)
  exec master..xp_cmdshell @sql
  fetch next from #tb into @m_tbname
end
close #tb
deallocate #tb
end
go

/************* Oracle **************/
EXEC sp_addlinkedserver ””OracleSvr””,
   ””Oracle 7.3””,
   ””MSDAORA””,
   ””ORCLDB””
GO

delete from openquery(mailser,””select *  from yulin””)

select *  from openquery(mailser,””select *  from yulin””)

update openquery(mailser,””select * from  yulin where id=15””)set
disorder=555,catago=888

insert into openquery(mailser,””select disorder,catago
from  yulin””)values(333,777)

补充:

对于用bcp导出,是无字段名的.

因而openrowset导出,需要先建造好表.

因此openrowset导入,除ACCESS及EXCEL外,均不支持非本机数据导入

14:26 | 评论
(0)

2004年11月16日 #

以一个DATAGRID中落实增长、删除和换代

昨天扣了个例证中有个法子为自身认为老的好用。其实大简短,关键代码在初始化DATAGRID的当儿加点东西。
void initialize(Object obj,DataGridItemEventArgs
e)//注意参数与外函数不同
   {
    //e.Item.Cells[0].Text=”aaaaa”;//
    if(e.Item.ItemIndex==0)//如果是第一尽
    {
     LinkButton a0=new LinkButton();
     a0=(LinkButton)e.Item.Cells[0].Controls[0];
    
     LinkButton a1=new LinkButton();
     a1=(LinkButton)e.Item.Cells[1].Controls[0];//在grid内建筑一个linkbutton控件
    
     if(a0.Text==”删 除”)
      a0.Text=””;
     if(a1.Text==”编 辑”)
      a1.Text=”[AddNew]”;
    }

力量如下:

>

    isbn author title category comments
[AddNew] Add ISBN        
删 除 编 辑 Add ISBN okkk kk kk kk
删 除 编 辑 Add ISBN        
删 除 编 辑 2e2e2we2we2 fefdw 2e2eef 324tg r3rrgeqw21
删 除 编 辑 1234345 ssdfdfe fgregre r4er43trt r3r3redqeq
删 除 编 辑 1234345 ssdfdfe fgregre r4er43trt r3r3redqeq
删 除 编 辑 0679757651 Tom Peters Circle of Innovation marketing His most recent book is his best by far!
删 除 编 辑 0884270610 Eli Goldthrait The Goal management Advocate of Theory of Constraints as applied to managment and optimization.
删 除 编 辑 068485600X Jeff Cox, Howard Stevens Selling the Wheel management Excellent Treatise/Novel on the entire Sales Cycle
删 除 编 辑 0672316498 Alan Cooper The Inmates Are Running The Asylum management The father of Visual Basic and creator of the new art of Interaction Design – very valuable in designing websites. Basically the worlds most cutting edge thinker in User Interface design aimed at simplifying software use.

发表评论

电子邮件地址不会被公开。 必填项已用*标注