SQL触发器使用教程和命名规范

SQL触发器使用教程和命名规范

1,触发器简介

触发器(Trigger)是数据库对象的一种,编码方式类似存储过程,与某张表(Table)相关联,当有DML语句对表进行操作时,可以引起触发器的执行,达到对插入记录一致性,正确性和规范性控制的目的。在当年C/S时代盛行的时候,由于客户端直接连接数据库,能保证数据库一致性的只有数据库本身,此时主键(Primary Key),外键(Foreign Key),约束(Constraint)和触发器成为必要的控制机制。而触发器的实现比较灵活,可编程性强,自然成为了最流行的控制机制。到了B/S时代,发展成4层架构,客户端不再能直接访问数据库,只有中间件才可以访问数据库。要控制数据库的一致性,既可以在中间件里控制,也可以在数据库端控制。很多的青睐Java的开发者,随之将数据库当成一个黑盒,把大多数的数据控制工作放在了Servlet中执行。这样做,不需要了解太多的数据库知识,也减少了数据库编程的复杂性,但同时增加了Servlet编程的工作量。从架构设计来看,中间件的功能是检查业务正确性和执行业务逻辑,如果把数据的一致性检查放到中间件去做,需要在所有涉及到数据写入的地方进行数据一致性检查。由于数据库访问相对于中间件来说是远程调用,要编写统一的数据一致性检查代码并非易事,一般采用在多个地方的增加类似的检查步骤。一旦一致性检查过程发生调整,势必导致多个地方的修改,不仅增加工作量,而且无法保证每个检查步骤的正确性。触发器的应用,应该放在关键的,多方发起的,高频访问的数据表上,过多使用触发器,会增加数据库负担,降低数据库性能。而放弃使用触发器,则会导致系统架构设计上的问题,影响系统的稳定性。

2,触发器示例

触发器代码类似存储过程,以PL/SQL脚本编写。下面是一个触发器的示例:

新建员工工资表salary

create table SALARY

(

EMPLOYEE_ID NUMBER, --员工ID

MONTH VARCHAR2(6), --工资月份

AMOUNT NUMBER --工资金额

)

创建与salary关联的触发器salary_trg_rai

1 Create or replace trigger salary_trg_rai

2 After insert on salary

3 For each row

4 declare

5 Begin

6 Dbms_output.put_line(‘员工ID:’ || :new.employee_id);

7 Dbms_output.put_line(‘工资月份:’ || :new.month);

8 Dbms_output.put_line(‘工资:’ || :new.amount);

9 Dbms_output.put_line(‘触发器已被执行’);

10 End;

打开一个SQL Window窗口(使用PL/SQL Developer工具),或在sqlplus中输入:

Insert into salary(employee_id, month, amount) values(1, ‘200606’, 10000);

执行后可以在sqlplus中,或在SQL Window窗口的Output中见到

员工ID:1

工资月份:200606

工资:10000

触发器已执行

在代码的第一行,定义了数据库对象的类型是trigger,定义触发器的名称是salary_trg_rai

第二行说明了这是一个after触发器,在DML操作实施之后执行。紧接着的insert说明了这是一个针对insert 操作的触发器,每个对该表进行的insert操作都会执行这个触发器。

第三行说明了这是一个针对行级的触发器,当插入的记录有n条时,在每一条插入操作时都会执行该触发器,总共执行n次。

Declare后面跟的是本地变量定义部分,如果没有本地变量定义,此部分可以为空

Begin和end括起来的代码,是触发器的执行部分,一般会对插入记录进行一致性检查,在本例中打印了插入的记录和“触发器已执行”。

其中:new对象表示了插入的记录,可以通过:new.column_name来引用记录的每个字段值

3,触发器语法和功能

触发器的语法如下

CREATE OR REPLACE TRIGGER trigger_name

ON table_name

[FOR EACH ROW]

WHEN (condition)

DECLARE

BEGIN

--触发器代码

END;

Trigger_name是触发器的名称。可以选择before或者after或instead of。Before 表示在DML语句实施前执行触发器,而after表示在在dml语句实施之后执行触发器,instead of触发器用在对视图的更新上。可以选择一个或多个DML语句,如果选择多个,则用or 分开,如:insert or update。Table_name是触发器关联的表名。

[FOR EACH ROW]为可选项,如果注明了FOR EACH ROW,则说明了该触发器是一个行级的触发器,DML语句处理每条记录都会执行触发器;否则是一个语句级的触发器,每个DML语句触发一次。

WHEN后跟的condition是触发器的响应条件,只对行级触发器有效,当操作的记录满足condition时,触发器才被执行,否则不执行。Condition中可以通过new对象和old对象(注意区别于前面的:new和:old,在代码中引用需要加上冒号)来引用操作的记录。

触发器代码可以包括三种类型:未涉及数据库事务代码,涉及关联表(上文语法中的table_name)数据库事务代码,涉及除关联表之外数据库事务代码。其中第一种类型代码只对数据进行简单运算和判断,没有DML语句,这种类型代码可以在所有的触发器中执行。第二种类型代码涉及到对关联表的数据操作,比如查询关联表的总记录数或者往关联表中插入一条记录,该类型代码只能在语句级触发器中使用,如果在行级触发器中使用,将会报ORA-04091错误。第三种类型代码涉及到除关联表之外的数据库事务,这种代码可以在所有触发器中使用。

从触发器的功能上来看,可以分成3类:

●重写列(仅限于before触发器)

●采取行动(任何触发器)

●拒绝事务(任何触发器)

“重写列”用于对表字段的校验,当插入值为空或者插入值不符合要求,则触发器用缺省值或另外的值代替,在多数情况下与字段的default属性相同。这种功能只能在行级before触发器中执行。“采取行动”针对当前事务的特点,对相关表进行操作,比如根据当前表插入的记录更新其他表,银行中的总帐和分户帐间的总分关系就可以通过这种触发器功能来维护。“拒绝事务”用在对数据的合法性检验上,当更新的数据不满足表或系统的一致性要求,则通过抛出异常的方式拒绝事务,在其上层的代码可以捕获这个异常并进行相应操作。

下面将通过举例说明,在例子中将触发器主体的语法一一介绍,读者可以在例子中体会触发器的功能。

4,例一:行级触发器之一

CREATE OR REPLACE TRIGGER salary_raiu

AFTER INSERT OR UPDATE OF amount ON salary

FOR EACH ROW

BEGIN

IF inserting THEN

dbms_output.put_line(‘插入’);

ELSIF updating THEN

dbms_output.put_line(‘更新amount列’);

END IF;

END;

以上是一个after insert和after update的行级触发器。在第二行中of amount on salary的意思是只有当amount列被更新时,update触发器才会有效。所以,以下语句将不会执行触发器:

Update salary set month = ‘200601’ where month = ‘200606’;

在触发器主体的if语句表达式中,inserting, updating和deleting可以用来区分当前是在做哪一种DML操作,可以作为把多个类似触发器合并在一个触发器中判别触发事件的属性。

5,例二:行级触发器之二

新建员工表employment

CREATE TABLE EMPLOYMENT

(

EMPLOYEE_ID NUMBER, --员工ID

MAXSALARY NUMBER --工资上限

)

插入两条记录

Insert into employment values(1, 1000);

Insert into employment values(2, 2000);

CREATE OR REPLACE TRIGGER salary_raiu

AFTER INSERT OR UPDATE OF amount ON salary

FOR EACH ROW

WHEN ( NEW.amount>= 1000 AND (old.amount IS NULL OR OLD.amount<= 500))

DECLARE

v_maxsalary NUMBER;

BEGIN

SELECT maxsalary

INTO v_maxsalary

FROM employment

WHERE employee_id = :NEW.employee_id;

IF :NEW.amount>v_maxsalary THEN

raise_application_error(-20000, '工资超限');

END IF;

END;

以上的例子引入了一个新的表employment,表中的maxsalary字段代表该员工每月所能分配的最高工资。下面的触发器根据插入或修改记录的employee_id,在employment表中查到该员工的每月最高工资,如果插入或修改后的amount超过这个值,则报错误。

代码中的when子句表明了该触发器只针对修改或插入后的amount值超过1000,而修改前的amount 值小于500的记录。New对象和old对象分别表示了操作前和操作后的记录对象。对于insert操作,由于当前操作记录无历史对象,所以old对象中所有属性是null;对于delete操作,由于当前操作记录没有更新对象,所以new对象中所有属性也是null。但在这两种情况下,并不影响old和new对象的引用和在触发器主体中的使用,和普通的空值作同样的处理。

在触发器主体中,先通过:new.employee_id,得到该员工的工资上限,然后在if语句中判断更新后的员工工资是否超限,如果超限则错误代码为-20000,错误信息为“工资超限”的自定义错误。其中的raise_application_error包含两个参数,前一个是自定义错误代码,后一个是自定义错误代码信息。其中自定义错误代码必须小于或等于-20000。执行完该语句后,一个异常被抛出,如果在上一层有exception子句,该异常将被捕获。如下面代码:

DECLARE

code NUMBER;

msg VARCHAR2(500);

BEGIN

INSERT INTO salary (employee_id, amount) VALUES (2, 5000);

EXCEPTION

WHEN OTHERS THEN

code := SQLCODE;

msg := substr(SQLERRM, 1, 500);

dbms_output.put_line(code);

dbms_output.put_line(msg);

END;

执行后,将在output中或者sqlplus窗口中见着以下信息:

-20000

ORA-20000: 工资超出限制

ORA-06512: 在"SCOTT.SALARY_RAI", line 9

ORA-04088: 触发器 'SCOTT.SALARY_RAI' 执行过程中出错

这里的raise_application_error相当于拒绝了插入或者修改事务,当上层代码接受到这个异常后,判断该异常代码等于-20000,可以作出回滚事务或者继续其他事务的处理。

以上两个例子中用到的inserting, updating, deleting和raise_application_error都是dbms_standard包中的函数,具体的说明可以参照Oracle的帮助文档。

create or replace package sys.dbms_standard is

procedure raise_application_error(num binary_integer, msg varchar2,

function inserting return boolean;

function deleting return boolean;

function updating return boolean;

function updating (colnam varchar2) return boolean;

end;

对于before和after行级触发器,:new和:old对象的属性值都是一样的,主要是对于在Oracle约束(Constraint)之前或之后的执行触发器的选择。需要注意的是,可以在before行触发器中更改:new 对象中的值,但是在after行触发器就不行。

下面介绍一种instead of触发器,该触发器主要使用在对视图的更新上,以下是instead of触发器的语法:

CREATE OR REPLACE TRIGGER trigger_name

INSTEAD OF ON view_name

[FOR EACH ROW]

WHEN (condition)

DECLARE

BEGIN

--触发器代码

END;

其他部分语法同前面所述的before和after语法是一样的,唯一不同的是在第二行用上了instead of 关键字。对于普通的视图来说,进行insert等操作是被禁止的,因为Oracle无法知道操作的字段具体是哪个表中的字段。但我们可以通过建立instead of触发器,在触发器主体中告诉Oracle应该更新,删除或者修改哪些表的哪部分字段。如:

6,例三:instead of触发器

新建视图

CREATE VIEW employee_salary(employee_id, maxsalary, MONTH, amount) AS

SELECT a.employee_id, a.maxsalary, b.MONTH, b.amount

FROM employment a, salary b

WHERE a.employee_id = b.employee_id

如果执行插入语句

INSERT INTO employee_salary(employee_id, maxsalary, MONTH, amount)

VALUES(10, 100000, '200606', 10000);

系统会报错:

ORA-01779:无法修改与非键值保存表对应的列

我们可以通过建立以下的instead of存储过程,将插入视图的值分别插入到两个表中:

create or replace trigger employee_salary_rii

instead of insert on employee_salary

for each ROW

DECLARE

v_cnt NUMBER;

BEGIN

--检查是否存在该员工信息

SELECT COUNT(*)

INTO v_cnt

FROM employment

WHERE employee_id = :NEW.employee_id;

IF v_cnt = 0 THEN

INSERT INTO employment

(employee_id, maxsalary)

VALUES

(:NEW.employee_id, :NEW.maxsalary);

END IF;

--检查是否存在该员工的工资信息

SELECT COUNT(*)

INTO v_cnt

FROM salary

WHERE employee_id = :NEW.employee_id

AND MONTH = :NEW.MONTH;

IF v_cnt = 0 THEN

INSERT INTO salary

(employee_id, MONTH, amount)

VALUES

(:NEW.employee_id, :NEW.MONTH, :NEW.amount);

END IF;

END employee_salary_rii;

该触发器被建立后,执行上述insert操作,系统就会提示成功插入一条记录。

但需要注意的是,这里的“成功插入一条记录”,只是Oracle并未发现触发器中有异常抛出,而根据insert 语句中涉及的记录数作出一个判断。若触发器的主体什么都没有,只是一个空语句,Oracle也会报“成功插入一条记录”。同样道理,即使在触发器主体里往多个表中插入十条记录,Oracle的返回也是“成功插入一条记录”。

行级触发器可以解决大部分的问题,但是如果需要对本表进行扫描检查,比如要检查总的工资是否超限了,用行级触发器是不行的,因为行级触发器主体中不能有涉及到关联表的事务,这时就需要用到语句级触发器。以下是语句级触发器的语法:

CREATE OR REPLACE TRIGGER trigger_name

ON table_name

DECLARE

BEGIN

--触发器主体

END;

从语法定义上来看,行级触发器少了for each row,也不能使用when子句来限定入口条件,其他部分都是一样的,包括insert, update, delete和instead of都可以使用。

7,例四:语句级触发器之一

CREATE OR REPLACE TRIGGER salary_saiu

AFTER INSERT OR UPDATE OF amount ON salary

DECLARE

v_sumsalary NUMBER;

BEGIN

SELECT SUM(amount) INTO v_sumsalary FROM salary;

IF v_sumsalary> 500000 THEN

raise_application_error(-20001, '总工资超过500000');

END IF;

END;

以上代码定义了一个语句级触发器,该触发器检查在insert和update了amount字段后操作后,工资表中所有工资记录累加起来是否超过500000,如果超过则抛出异常。从这个例子可以看出,语句级触发器可以对关联表表进行扫描,扫描得到的结果可以用来作为判断一致性的标志。需要注意的是,在before 语句触发器主体和after语句触发器主体中对关联表进行扫描,结果是不一样的。在before语句触发器主体中扫描,扫描结果将不包括新插入和更新的记录,也就是说当以上代码换成before触发器后,以下语句将不报错:

INSERT INTO salary(employee_id, month, amount) VALUEs(2, '200601', 600000)

这是因为在主体中得到的v_sumsalary并不包括新插入的600000工资。

另外,在语句级触发器中不能使用:new和:old对象,这一点和行级触发器是显著不同的。如果需要检查插入或更新后的记录,可以采用临时表技术。

临时表是一种Oracle数据库对象,其特点是当创建数据的进程结束后,进程所创建的数据也随之清除。进程与进程不可以互相访问同一临时表中对方的数据,而且对临时表进行操作也不产生undo日志,减少了数据库的消耗。具体有关临时表的知识,可以参看有关书籍。

为了在语句级触发器中访问新插入后修改后的记录,可以增加行级触发器,将更新的记录插入临时表中,然后在语句级触发器中扫描临时表,获得修改后的记录。临时表的表结构一般与关联表的结构一致。

8,例五:语句级触发器之二

目的:限制每个员工的总工资不能超过50000,否则停止对该表操作。

创建临时表

create global temporary table SALARY_TMP

(

EMPLOYEE_ID NUMBER,

MONTH VARCHAR2(6),

AMOUNT NUMBER

)

on commit delete rows;

为了把操作记录插入到临时表中,创建行级触发器:

CREATE OR REPLACE TRIGGER salary_raiu

AFTER INSERT OR UPDATE OF amount ON salary

FOR EACH ROW

BEGIN

INSERT INTO salary_tmp(employee_id, month, amount)

VALUES(:NEW.employee_id, :NEW.MONTH, :NEW.amount);

END;

该触发器的作用是把更新后的记录信息插入到临时表中,如果更新了多条记录,则每条记录都会保存在临时表中。

创建语句级触发器:

CREATE OR REPLACE TRIGGER salary_sai

AFTER INSERT OR UPDATE OF amount ON salary

DECLARE

v_sumsalary NUMBER;

BEGIN

FOR cur IN (SELECT * FROM salary_tmp) LOOP

SELECT SUM(amount)

INTO v_sumsalary

FROM salary

WHERE employee_id = cur.employee_id;

IF v_sumsalary> 50000 THEN

raise_application_error(-20002, '员工累计工资超过50000');

END IF;

DELETE FROM salary_tmp;

END LOOP;

END;

该触发器首先用游标从salary_tmp临时表中逐条读取更新或插入的记录,取employee_id,在关联表salary中查找所有相同员工的工资记录,并求和。若某员工工资总和超过50000,则抛出异常。如果检查通过,则清空临时表,避免下次检查相同的记录。

执行以下语句:

INSERT INTO salary(employee_id, month, amount) VALUEs(7, '200601', 20000);

INSERT INTO salary(employee_id, month, amount) VALUEs(7, '200602', 20000);

INSERT INTO salary(employee_id, month, amount) VALUEs(7, '200603', 20000);

在执行第三句时系统报错:

ORA-20002:员工累计工资超过50000

查询salary表,发现前两条记录正常插入了,第三条记录没有插入。

如果系统结构比较复杂,而且触发器的代码比较多,在触发器主体中写过多的代码,对于维护来说是一个困难。这时可以将所有触发器的代码写到同一个包中,不同的触发器代码以不同的存储过程封装,然后触发器主体中调用这部分代码。

9,例六:用包封装触发器代码

目的:改写例五,封装触发器主体代码

创建代码包:

CREATE OR REPLACE PACKAGE BODY salary_trigger_pck IS

PROCEDURE load_salary_tmp(i_employee_id IN NUMBER,

i_month IN VARCHAR2,

i_amount IN NUMBER) IS

BEGIN

INSERT INTO salary_tmp VALUES (i_employee_id, i_month, i_amount);

END load_salary_tmp;

PROCEDURE check_salary IS

v_sumsalary NUMBER;

BEGIN

FOR cur IN (SELECT * FROM salary_tmp) LOOP

SELECT SUM(amount)

INTO v_sumsalary

FROM salary

WHERE employee_id = cur.employee_id;

IF v_sumsalary> 50000 THEN

raise_application_error(-20002, '员工累计工资超过50000');

END IF;

DELETE FROM salary_tmp;

END LOOP;

END check_salary;

END salary_trigger_pck;

包salary_trigger_pck中有两个存储过程,load_salary_tmp用于在行级触发器中调用,往salary_tmp临时表中装载更新或插入记录。而check_salary用于在语句级触发器中检查员工累计工资是否超限。

修改行级触发器和语句级触发器:

CREATE OR REPLACE TRIGGER salary_raiu

AFTER INSERT OR UPDATE OF amount ON salary

FOR EACH ROW

BEGIN

salary_trigger_pck.load_salary_tmp(:NEW.employee_id, :NEW.MONTH, :NEW.amount); END;

CREATE OR REPLACE TRIGGER salary_sai

AFTER INSERT OR UPDATE OF amount ON salary

BEGIN

salary_trigger_pck.check_salary;

END;

这样主要代码就集中到了salary_trigger_pck中,触发器主体中只实现了一个调用功能。

10,触发器命名规范

为了方便对触发器命名和根据触发器名称了解触发器含义,需要定义触发器的命名规范:

Trigger_name = table_name_trg_

触发器名限于30个字符。必须缩写表名,以便附加触发器属性信息。

基于行级(row)还是语句级(statement)的触发器

after, before或者是instead of触发器

触发事件是insert,update还是delete。如果有多个触发事件则连着写

例如:

Salary_rai salary表的行级after触发器,触发事件是insert

Employee_sbiud employee表的语句级before触发器,触发事件是insert,update和delete

SQL Server2008触发器学习笔记

触发器 一﹕触发器是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约束。 二﹕SQL Server为每个触发器都创建了两个专用表﹕Inserted表和Deleted表。这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后﹐与该触发器相关的这两个表也被删除。Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。 三﹕Instead of 和After触发器 SQL Server提供了两种触发器﹕Instead of 和After 触发器。 这两种触发器的差别在于他们被激活的操作﹕ Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外﹐Instead of 触发器也可以用于视图﹐用来扩展视图可以支持的更新操作。 After触发器在一个Insert,Update或Deleted语句之后执行﹐进行约束检查等动作都在After 触发器被激活之前发生。After触发器只能用于表。一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器﹐一个表的每个修改动作都可以有多个After触发器。 INSTEAD OF触发器被用于更新那些没有办法通过正常方式更新的视图。通常不能在一个基于连接的视图上进行DELETE操作,可以编写一个INSTEAD OF DELETE触发器来实现删除。可以访问那些如果视图是一个真正的表时已经被删除的数据行,它将把删除的行存储在deleted临时表中。 本次练习将通过具体的例子介绍如何使用INSTEAD OF触发器,使读者掌握INSTEAD OF 触发器的使用方法。 向student表中插入数据时,检查学号是否存在于student表中,如存在则进行插入操作,否则就不插入,具体语句如下所示: CREATE TRIGGER [checkid] ON dbo.student INSTEAD OF insert AS IF NOT EXISTS(SELECT * FROM dbo.student WHERE ID=(SELECT ID FROM INSERTED)) BEGIN ROLLBACK TRANSACTION PRINT '要处理记录的学号不存在!' END ELSE BEGIN INSERT NTO dbo.student select * from inserted

软件工程-数据库设计规范与命名规则

数据库设计规范、技巧与命名规范 一、数据库设计过程 数据库技术是信息资源管理最有效的手段。 数据库设计是指:对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,有效存储数据, 满足用户信息要求和处理要求。 数据库设计的各阶段: A、需求分析阶段:综合各个用户的应用需求(现实世界的需求)。 B、在概念设计阶段:形成独立于机器和各DBMS产品的概念模式(信息世界模型),用E-R图来描述。 C、在逻辑设计阶段:将E-R图转换成具体的数据库产品支持的数据模型,如关系模型,形成数据库逻辑模式。 然后根据用户处理的要求,安全性的考虑,在基本表的基础上再建立必要的视图(VIEW)形成数据的外模式。 D、在物理设计阶段:根据DBMS特点和处理的需要,进行物理存储安排,设计索引,形成数据库内模式。 1. 需求分析阶段 需求收集和分析,结果得到数据字典描述的数据需求(和数据流图描述的处理需求)。 需求分析的重点:调查、收集与分析用户在数据管理中的信息要求、处理要求、安全性与完整性要求。 需求分析的方法:调查组织机构情况、各部门的业务活动情况、协助用户明确对新系统的各种要求、确定新系统的边界。 常用的调查方法有:跟班作业、开调查会、请专人介绍、询问、设计调查表请用户填写、查阅记录。 分析和表达用户需求的方法主要包括自顶向下和自底向上两类方法。自顶向下的结构化分析方法(Structured Analysis, 简称SA方法)从最上层的系统组织机构入手,采用逐层分解的方式分析系统,并把每一层用数据流图和数据字典描述。 数据流图表达了数据和处理过程的关系。系统中的数据则借助数据字典(Data Dictionary,简称DD)来描述。 2. 概念结构设计阶段 通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型,可以用E-R图表示。 概念模型用于信息世界的建模。概念模型不依赖于某一个DBMS支持的数据模型。概念模型可以转换为计算机上某一 DBMS 支持的特定数据模型。 概念模型特点: (1) 具有较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识。 (2) 应该简单、清晰、易于用户理解,是用户与数据库设计人员之间进行交流的语言。 概念模型设计的一种常用方法为IDEF1X方法,它就是把实体-联系方法应用到语义数据模型中的一种语义模型化技术, 用于建立系统信息模型。 使用IDEF1X方法创建E-R模型的步骤如下所示:

SQL触发器使用教程和命名规范

SQL触发器使用教程和命名规范 1,触发器简介 触发器(Trigger)是数据库对象的一种,编码方式类似存储过程,与某张表(Table)相关联,当有DML语句对表进行操作时,可以引起触发器的执行,达到对插入记录一致性,正确性和规范性控制的目的。在当年C/S时代盛行的时候,由于客户端直接连接数据库,能保证数据库一致性的只有数据库本身,此时主键(Primary Key),外键(Foreign Key),约束(Constraint)和触发器成为必要的控制机制。而触发器的实现比较灵活,可编程性强,自然成为了最流行的控制机制。到了B/S时代,发展成4层架构,客户端不再能直接访问数据库,只有中间件才可以访问数据库。要控制数据库的一致性,既可以在中间件里控制,也可以在数据库端控制。很多的青睐Java的开发者,随之将数据库当成一个黑盒,把大多数的数据控制工作放在了Servlet中执行。这样做,不需要了解太多的数据库知识,也减少了数据库编程的复杂性,但同时增加了Servlet编程的工作量。从架构设计来看,中间件的功能是检查业务正确性和执行业务逻辑,如果把数据的一致性检查放到中间件去做,需要在所有涉及到数据写入的地方进行数据一致性检查。由于数据库访问相对于中间件来说是远程调用,要编写统一的数据一致性检查代码并非易事,一般采用在多个地方的增加类似的检查步骤。一旦一致性检查过程发生调整,势必导致多个地方的修改,不仅增加工作量,而且无法保证每个检查步骤的正确性。触发器的应用,应该放在关键的,多方发起的,高频访问的数据表上,过多使用触发器,会增加数据库负担,降低数据库性能。而放弃使用触发器,则会导致系统架构设计上的问题,影响系统的稳定性。 2,触发器示例 触发器代码类似存储过程,以PL/SQL脚本编写。下面是一个触发器的示例: 新建员工工资表salary create table SALARY ( EMPLOYEE_ID NUMBER, --员工ID MONTH VARCHAR2(6), --工资月份 AMOUNT NUMBER --工资金额 ) 创建与salary关联的触发器salary_trg_rai 1 Create or replace trigger salary_trg_rai 2 After insert on salary 3 For each row

SQL server数据库设计实例

数据库原理与应用 课程设计A报告 姓名:袁一帆学号:20121480 学院(系):管理学院专业:信息管理与信息系统

班级:12级信管1 班

襄阳迈博信息科技有限公司企业考勤管理系统 一、系统目标设计 1系统开发的总体任务是实现企业员工考勤管理的系统化、规范化、和自动化。 2能够和人事管理系统、工资管理系统相结合,真正实现企业高效、科学、现代化的员工管理。 二、开发实际思想 1尽量采用公司现有软硬件环境,及先进的管理系统开发方案,从而达到充分利用公司现有资源,提高系统开发水平和应用效果的目的。 2员工考勤管理系统能够和考勤机相连接,从而完成自动、高效、科学的考勤信息输入。 3系统采用模块化程序设计方法,既便与系统功能的各种组合和修该,又便于未参与开发的技术维护人员补充、维护。 系统应具备数据库维护功能,即使根据用户需求进行数据的添加、删除、修改、被分等操作。 系统需求分析 1 考勤管理涉及企业人事管理的多个方面,如员工职务升迁、工资发放、奖金发放、员工医疗保险发放等等。本利自重的考勤管理系统需要完成功能主要有以下几点。 2 员工考勤信息处理。该莫完成员工考勤情况的输入、修改等操作。如果企业内有考勤机,可以将它的输出处理后,形成考勤管理系统考勤模块的

输入。 3 企业缺勤类型的设定。 4 企业考勤统计。该模块可对某个员工进行考勤情况的统计,生成统计报表。 5 缺勤时间,缺勤类型对工资的影响 6 缺勤时间,缺勤类型对升职的影响 数据字典 数据项 表1 名称员工编号 说明每个员工拥有唯一的编号 类型字符型 长度 4 有关数据存储员工基本信息存储 表2 名称员工姓名

数据库表及字段命名、设计规范

数据库表及字段命名、设计规范1、命名规范 1.1数据表的命名规范: 1)表的前缀应该用系统或模块的英文名的缩写(全部大写或首字母大写)。如果系统功能简单,没有划分为模块,则可以以系统英文名称的缩写作为前缀,否则以各模块的英文名称缩写作为前缀。例如:如果有一个模块叫做BBS(缩写为BBS),那么你的数据库中的所有对象的名称都要加上这个前缀:BBS_ + 数据库对象名称,BBS_CustomerInfo标示论坛模块中的客户信息表。 2)表的名称必须易于理解,使用能表达表功能的英文单词或缩写英文单词,无论是完整英文单词还是缩写英文单词,单词首字母必须大写。如果当前表可用一个英文单词表示的,请用完整的英文单词来表示;例如:系统资料中的客户表的表名可命名为:SYS_Customer。如果当前表需用两个或两个以上的单词来表示时,尽量以完整形式书写,如太长可采用两个英文单词的缩写形式;例如:系统资料中的客户物料表可命名为:SYS_CustItem。 3)表的名称一般使用名词或者动宾短语 4)表名称不应该取得太长(一般不超过三个英文单词)。 5)在命名表时,用单数形式表示名称。例如,使用Employee,而不是Employees。 6)对于有主明细的表来说。明细表的名称为:主表的名称+ 字符Dts。例如:采购定单的名称为:PO_Order,则采购定单的明细表为:PO_OrderDts 对于有主明细的表来说,明细表必须包含两个字段:主表关键字、SN,SN字段的类型为int 型,目的为与主表关键字联合组成明细表的关键字,以及标示明细记录的先后顺序,如1,2,3……。 7)表必须填写描述信息

数据库表字段命名规范

数据库表字段命名规范 摘要:当前研发工作中经常出现因数据库表、数据库表字段格式不规则而影响开发进度的问题,在后续开发使用原来数据库表时,也会因为数据库表的可读性不够高,表字段规则不统一,造成数据查询,数据使用效率低的问题,所以有必要整理出一套合适的数据库表字段命名规范来解决优化这些问题。 本文是一篇包含了数据库命名、数据库表命名、数据库表字段命名及SQL语言编码的规范文档,针对研发中易产生的问题和常见错误做了一个整理和修改,为日后涉及到数据库相关的研发工作做好准备。 一、数据库命名规范 采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成,命名简洁明确,多个单词用下划线'_'分隔,一个项目一个数据库,多个项目慎用同一个数据库 二、数据库表命名规范 2.1数据表命名规范 (1)采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成,命名简洁明确,多个单词用下划线'_'分隔 (2)全部小写命名,禁止出现大写 (3)禁止使用数据库关键字,如:name,time ,datetime,password等(4)表名称不应该取得太长(一般不超过三个英文单词)

(5)表的名称一般使用名词或者动宾短语 (6)用单数形式表示名称,例如,使用employee,而不是employees 明细表的名称为:主表的名称+字符dtl(detail缩写) 例如:采购定单的名称为:po_order,则采购定单的明细表为:po_orderdtl (7)表必须填写描述信息(使用SQL语句建表时) 2.2命名规范 ①模块_+功能点示例:alllive_log alllive_category ②功能点示例:live message ③通用表示例:all_user 2.3待优化命名示例 ①冗余: 错误示例:yy_alllive_video_recomment yy_alllive_open_close_log 说明:去除项目名,简化表名长度,去”yy_” ②相同类别表命名存在差异,管理性差 错误示例:yy_all_live_category yy_alllive_comment_user 说明:去除项目名,统一命名规则,均为”yy_alllive_”开头即可 ③命名格式存在差异 错误示例:yy_showfriend yy_user_getpoints yy_live_program_get

SQL触发器基本教程

一、创建一个简单的触发器 触发器是一种特殊的存储过程,类似于事件函数,SQL Server? 允许为INSERT、UPDATE、DELETE 创建触发器,即当在表中插入、更新、删除记录时,触发一个或一系列T-SQL语句。触发器可以在查询分析器里创建,也可以在表名上点右键->“所有任务”->“管理触发器”来创建,不过都是要写T-SQL 语句的,只是在查询分析器里要先确定当前操作的数据库。 创建触发器用CREATE TRIGGER CREATE TRIGGER 触发器名称 ON 表名 FOR I NSERT、UPDATE 或DELETE AS T-SQL 语句 注意:触发器名称是不加引号的。 如下是联机丛书上的一个示例,当在titles 表上更改记录时,发送邮件通知MaryM。CREATE TRIGGER reminder ON titles FOR INSERT, UPDATE, DELETE AS EXEC master..xp_sendmail 'MaryM', 'Don''t forget to print a report for the distributors.' 二、删除触发器 用查询分析器删除 在查询分析器中使用drop trigger 触发器名称来删除触发器。 也可以同时删除多个触发器:drop trigger 触发器名称,触发器名称... 注意:触发器名称是不加引号的。在删除触发器之前可以先看一下触发器是否存在: if Exists(select name from sysobjects where name=触发器名称and xtype='TR') 用企业管理器删除 在企业管理器中,在表上点右键->“所有任务”->“管理触发器”,选中所要删除的触发器,然后点击“删除”。 三、重命名触发器 用查询分析器重命名 exec sp_rename 原名称, 新名称 sp_rename 是SQL Server? 自带的一个存储过程,用于更改当前数据库中用户创建的对象的名称,如表名、列表、索引名等。

数据库设计规范

数据库设计规范 V 1.0 2007-8-28

目录 1) 目的 (3) 2) 范围 (3) 3) 术语 (3) 4) 设计概要 (3) 5) 命名规范(逻辑对象) (4) 6) 数据库对象命名 (6) 7) 脚本注释 (8) 8) 数据库操作原则 (9) 9) 常用字段命名(参考) (9)

1) 目的 为了统一公司软件开发的设计过程中关于数据库设计时的命名规范和具体工作时的编程规范,便于交流和维护,特制定此规范。 2) 范围 本规范适用于开发组全体人员,作用于软件项目开发的数据库设计、维护阶段。 3) 术语 数据库对象:在数据库软件开发中,数据库服务器端涉及的对象包括物理结构和逻辑结构的对象。 物理结构对象:是指设备管理元素,包括数据文件和事务日志文件的名称、大小、目录规划、所在的服务器计算极名称、镜像等,应该有具体的配置规划。一般对数据库服务器物理设备的管理规程,在整个项目/产品的概要设计阶段予以规划。 逻辑结构对象:是指数据库对象的管理元素,包括数据库名称、表空间、表、字段/域、视图、索引、触发器、存储过程、函数、数据类型、数据库安全性相关的设计、数据库配置有关的设计以及数据库中其他特性处理相关的设计等。 4) 设计概要 ?设计环境 数据库:ORACLE 9i 、MS SQL SERVER 2000 等 操作系统:LINUX 7.1以上版本,显示图形操作界面; RedHat 9 以上版本 WINDOWS 2000 SERVER 以上 ?设计使用工具 使用PowerDesigner 做为数据库的设计工具,要求为主要字段做详尽说 明。对于SQL Server 尽量使用企业管理器对数据库进行设计,并且要求 对表,字段编写详细的说明(这些将作为扩展属性存入SQL Server中) 通过PowerDesigner 定制word格式报表,并导出word文档,作为数据 字典保存。(PowerDesigner v10 才具有定制导出word格式报表的功能)。

SQL触发器实例

--建立触发器,显示修改人数 create trigger d1 on jun for insert,update as select '你正在修改数据' declare @a varchar(20) select @a=str(@@rowcount)+'个学生被修改' select @a select * from jun return insert into jun(爱好) values('跑步') update jun set 爱好='打球' where 学号<='103' --建立触发器,当男生人数在6个以内可以加入,否则不能加入 create trigger i1 on zg for insert as if((select count(性别) from zg where 性别='男')>6) select '不能插入,男生人数已满。' else select'插入成功' select * from zg insert into zg(学号,姓名,性别) values(20100636,'江渝','男') --建立触发器,如果语文成绩在200以内可以修改,否则不能修改 create trigger u1 on zg for update as if((select max(语文) from zg )>200) begin select '你不能修改' rollback end else select '修改成功' select * from zg update zg set 语文=语文+10 where 姓名='唐荣强' update zg set 语文=语文-20 where 姓名='张军' update zg set 语文=语文+30 where 姓名='张军'

SQL触发器实例讲解

SQL触发器实例讲解 2008-11-27 16:16:45| 分类:PROCEDURE | 标签:|字号大中小订阅 SQL触发器实例1 定义:何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete 事件。 我为什么要使用触发器?比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 .... ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号 StudentID int , --学号 BorrowDate datetime, --借出时间 ReturnDAte Datetime, --归还时间 ... ) 用到的功能有: 1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号); 2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。 等等。 这时候可以用到触发器。对于1,创建一个Update触发器: Create Trigger truStudent On Student --在Student表中创建触发器 for Update --为什么事件触发 As --事件触发后所要做的事情 if Update(StudentID) begin Update BorrowRecord Set StudentID=i.StudentID

删除 SQL Server 的实例

删除SQL Server 的特定实例 若要删除SQL Server 的特定实例,请按照下列步骤操作: 1.找到并删除%drive%:\Program Files\Microsoft SQL Server\MSSQL\Binn 文件 夹,其中%drive%是要删除的SQL Server 实例的位置。 2.找到以下注册表项: o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer 注意:如果要删除默认实例,则必须删除除Client项以外的所有项。 o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server 必须使用Regedt32.exe 来编辑要删除的实例的InstalledInstances 值。默认实例的显示名称为MSSQLSERVER,而命名实例的显示名称则为给该 实例指定的名称。 注意:不能使用Regedit.exe 编辑该值;您必须使用Regedt32.exe。 注意:如果这是SQL Server 2000 的群集实例,请为群集中的每个节点重复执行这些步骤。 删除SQL Server 的所有已知实例 若要删除SQL Server 的所有已知实例,请按照下列步骤操作: 1.找到并删除%drive%:\Program Files\Microsoft SQL Server\MSSQL\Binn 文件 夹。 2.找到并删除以下注册表项: o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server 3.找到并删除以下注册表项: o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQL Server o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SQLSER VERAGENT o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQL ServerADHelper 4.步骤3 中的三个注册表项对应于Microsoft SQL Server 2000 的默认实例。命名实例 对应的注册表项与步骤 3 中列出的注册表项类似,但后面带有$instance_name,因

SQL触发器全过程(含实例讲解)

SQL触发器全过程 第一、概述 一:触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约`束。 二: SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted 表。这两个表由系统来维护,它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后,与该触发器相关的这两个表也被删除。 Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。 Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。 三:instead of 和 After触发器 SQL Server2000提供了两种触发器:Instead of 和After 触发器。这两种触发器的差别在于他们被激活的同: Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外,Instead of 触发器也可以用于视图,用来扩展视图可以支持的更新操作。 After触发器在一个Insert,Update或Deleted语句之后执行,进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。

一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器,一个表的每个修改动作都可以有多个After触发器。 四:触发器的执行过程 如果一个Insert﹑update或者delete语句违反了约束,那幺After触发器不会执行,因为对约束的检查是在After触发器被激动之前发生的。所以After 触发器不能超越约束。 Instead of 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立,其它任何操作还没有发生时被执行。因为Instead of 触发器在约束之前执行,所以它可以对约束进行一些预处理。 五:使用T-SQL语句来创建触发器 基本语句如下: create trigger trigger_name on {table_name | view_name} {for | After | Instead of } [ insert, update,delete ] as sql_statement

SqlServer触发器的原理及案例

SqlServer触发器的原理及案例合理的选用触发器会让你的系统更高效 2010 Ssc

目录 第1章何为触发器 (3) 1.1 触发器的'本质' (3) 1.2 这样做带来的'功能': (3) 1.3 触发器的作用 (3) 1.4 说明: (3) 第2章对触发器3种操作的分析 (4) 2.1 创建触发器 (4) 2.2 学习案例 (5) 2.2.1 建立表 (5) 2.2.2 触发器练习1 (5) 2.2.3 触发器练习2: (6) 第3章图形化操作触发器 (7) 3.1 查看触发器情况 (7) 第4章触发器中的变量操作 (11) 第5章SQL触发器语法参考 (11)

第1章何为触发器 1.1触发器的'本质' 触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录、更改记录或者删除记录时,当事件发生时,才被自动地激活。 1.2这样做带来的'功能': 触发器可以用来对表实施复杂的完整性约束,保持数据的一致性,当触发器所保护的数据发生改变时,触发器会自动被激活,响应同时执行一定的操作(对其它相关表的操作),从而保证对数据的不完整性约束或不正确的修改。触发器可以查询其它表,同时也可以执行复杂的T-SQL语句。触发器和引发触发器执行的命令被当作一次事务处理,因此就具备了事务的所有特征。 注意:'事务具备什么特征?在触发器中的作用?' 如果发现引起触发器执行的T-SQL语句执行了一个非法操作,比如关于其它表的相关性操作,发现数据丢失或需调用的数据不存在,那么就回滚到该事件执行前的SQL SERVER数据库状态。 1.3触发器的作用 触发器可以对数据库进行级联修改,这一点刚才已经说过了。需要说明的是:'触发器和约束的关系和区别' (1)一般来说,使用约束比使用触发器效率更高。 (2)同时,触发器可以完成比CHECK约束更复杂的限制。 1.4说明: 1.与CHECK约束不同,在触发器中可以引用其它的表。 2.触发器可以发现改变前后表中数据的不一致,并根据这些不同来进行相应的操作。

数据库命名规范(表、字段名)

数据库命名规范(表、字段名) 一. 实体和属性的命名 1常用单词已经进行了缩写,在命名过程当中,根据语义拼凑缩写即可。注意,由于ORCAL 数据库会将字段名称统一成大写或者小写中的一种,所以要求加上下划线 举例: 定义的缩写Sales: Sal 销售; Order: Ord 订单; Detail: Dtl 明细; 则销售订单名细表命名为:Sal_Ord_Dtl; 2.如果表或者是字段的名称仅有一个单词,那么建议不使用缩写,而是用完整的单词。举例: 定义的缩写Material Ma 物品; 物品表名为:Material, 而不是Ma. 但是字段物品编码则是:Ma_ID;而不是Material」。 3.所有的存储值列表的表前面加上前缀Z 目的是将这些值列表类排序在数据库最后。 4.所有的冗余类的命名(主要是累计表)前面加上前缀X 冗余类是为了提高数据库效率,非规范化数据库的时候加入的字段。或者表 5.关联类通过用下划线连接两个基本类之后,再加前缀R的方式命名,后面按照字母顺序罗列两个表名或者表名的缩写。 关联表用于保存多对多关系。 如果被关联的表名大于10个字母,必须将原来的表名的进行缩写。如果没有其他原因,建 议都使用缩写。 举例:表Object与自身存在多对多的关系,则保存多对多关系的表命名为:R_Object ; 表Depart和Employee;存在多对多的关系;则关联表命名为R_Dept_Emp 6.每一个表都将有一个自动ID作为主健,逻辑上的主健作为第一组候选主健来定义,如果是数据库自动生成的编码,统一命名为:ID;如果是自定义的逻辑上的编码则用缩写加“ID” 的方法命名。 举例:销售订单的编号字段命名:Sal_Ord」D ;如果还存在一个数据库生成的自动编号,则 命名为:ID。

SQL触发器语法参考

SQL触发器语法参考 CreateTRIGGER trigger_name ON { table | view } [ WITH ENCRYPTION ] { { { FOR |AFTER | INSTEAD OF } { [ Insert ] [ , ] [ Update ] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS [ { IF Update ( column ) [ { AND | or } Update ( column ) ] [ ...n ] | IF ( COLUMNS_UpdateD ( ) { bitwise_operator } updated_bitmask) { comparison_operator } column_bitmask [ ...n ] } ] sql_statement [ ...n ] } } 参数 trigger_name 是触发器的名称。触发器名称必须符合标识符规则,并且在数据库中必须唯一。可以选择是否指定触发器所有者名称。 Table | view 是在其上执行触发器的表或视图,有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。 WITH ENCRYPTION 加密syscomments 表中包含Create TRIGGER语句文本的条目。使用WITH ENCRYP TION 可防止将触发器作为SQL Server复制的一部分发布。 AFTER 指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。 如果仅指定FOR 关键字,则AFTER是默认设置。 不能在视图上定义AFTER 触发器。

数据库命名设计规范

数据库命名、设计规范 一、数据库表及字段 1.数据库表的命名规范: 表的前缀应该用系统或模块的英文名的缩写(全部大写)。如果系统功能简单,没有划分为模块,则可以以系统英文名称的缩写作为前缀,否则以各模块的英文名称缩写作为前缀。例如:如果有一个模块叫做BBS(缩写为BBS),那么你的数据库中的所有对象的名称都要加上这个前缀:BBS_ + 数据库对象名称,BBS_CustomerInfo标示论坛模块中的客户信息表。 表的名称必须是易于理解,能表达表的功能的英文单词或缩写英文单词,无论是完整英文单词还是缩写英文单词,单词首字母必须大写。如果当前表可用一个英文单词表示的,请用完整的英文单词来表示;例如:系统资料中的客户表的表名可命名为:SYS_Customer。如果当前表需用两个或两个以上的单词来表示时,尽量以完整形式书写,如太长可采用两个英文单词的缩写形式;例如:系统资料中的客户物料表可命名为:SYS_CustItem。 表名称不应该取得太长(一般不超过三个英文单词)。表名长度不能超过30个字符,表名中含有单词全部采用单数形式,单词首字母必须大写。在命名表时,用单数形式表示名称。例如,使用 Employee,而不是 Employees。对于有主明细的表来说。明细表的名称为:主表的名称 + 字符Dts。例如:采购定单的名称为:PO_Order,则采购定单的明细表为:PO_OrderDts;对于有主明细的表来说,明细表必须包含两个字段:主表关键字、SN,SN字段的类型为int型,目的为与主表关键字联合组成明细表的关键字,以及标示明细记录的先后顺序,如1,2,3……。表必须填写描述信息,后台表名尽量与前台表名相同,后台独有的表应以_b作为后缀。如r_gggd_b。 数据库表的命名采用如下规则: 1)表名用模块名_开头,表名长度不能超过30个字符,表名中含有单词全部采用单数形式,单词首字母必须大写。 2)多个单词间用下划线(_)进行连接。若库中有多个系统,表名采用系统名称+单词或多个单词,系统名是开发系统的缩写,如VNET。

SQL触发器实例讲解

SQL触发器实例讲解 SQL 资料2009-07-23 14:44:07 阅读6072 评论9 字号:大中小订阅 定义:何为触发器?在SQL Serv er里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete 事件。 我为什么要使用触发器?比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 .... ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号 StudentID int , --学号 BorrowDate datetime, --借出时间 ReturnDAte Datetime, --归还时间 ... ) 用到的功能有: 1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号); 2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。 等等。 这时候可以用到触发器。对于1,创建一个Update触发器: Create Trigger truStudent On Student --在Student表中创建触发器 f or Update --为什么事件触发 As --事件触发后所要做的事情 if Update(StudentID) begin Update BorrowRecord Set StudentID=i.StudentID From BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted临时表 Where br.StudentID=d.StudentID end

SQL游标及触发器实例

SQL Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Declare @barCode varchar(50)--声明变量用于存放游标结果 DECLARE CsrName CURSOR FOR--声明游标 select barCode from eachBook --游标数据来源 BEGIN OPEN CsrName --打开游标 FETCH FROM CURSUBOK INTO @barCode--获得来源的一行记录放入变量 WHILE @@FETCH_STATUS = 0 BEGIN -----------------------------------------------------针对每个结果做的操作 print @barcode ----------------------------------------------------------------------------End FETCH NEXT FROM CsrName INTO @barCode --处理下一行数据 CLOSE CsrName --游标用完了要关掉 END 总结:一般sql语句是面向集合的,游标是面向集合里面的行的,相当于获取一行数据->处理->获得下一行数据->处理这样一个循环。能不用游标就尽量不要用游标,性能很烂 --两种触发器,after为表sql语句执行之后操作,INSTEAD OF为之前操作 create trigger tgr_name--创建触发器 on classes --在classes表上 for insert--当classes表插入数据是触发as里面的操作(for 有after默认值,所以是sql 语句执行完了执行) --,有insert、update、delete三种操作类型。 as declare @id int;--定义变量用来临时存放数据 select @id = id from inserted; --在inserted表中查询已经插入记录信息,update就有个updated表,deleted就是deleted表 print '刚刚插入的记录的ID是'+@id; GO

数据库表及字段命名、设计规范

数据库表及字段命名、设计规范 1、命名规范 1.1数据表的命名规范: 1)表的前缀应该用系统或模块的英文名的缩写(全部大写或首字母大写)。如果系统功能简单,没有划分为模块,则可以以系统英文名称的缩写作为前缀,否则以各模块的英文名称缩写作为前缀。例如:如果有一个模块叫做BBS(缩写为BBS),那么你的数据库中的所有对象的名称都要加上这个前缀:BBS_ + 数据库对象名称,BBS_CustomerInfo标示论坛模块中的客户信息表。 2)表的名称必须易于理解,使用能表达表功能的英文单词或缩写英文单词,无论是完整英文单词还是缩写英文单词,单词首字母必须大写。如果当前表可用一个英文单词表示的,请用完整的英文单词来表示;例如:系统资料中的客户表的表名可命名为:SYS_Customer。如果当前表需用两个或两个以上的单词来表示时,尽量以完整形式书写,如太长可采用两个英文单词的缩写形式;例如:系统资料中的客户物料表可命名为:SYS_CustItem。 3)表的名称一般使用名词或者动宾短语 4)表名称不应该取得太长(一般不超过三个英文单词)。 5)在命名表时,用单数形式表示名称。例如,使用 Employee,而不是 Employees。 6)对于有主明细的表来说。明细表的名称为:主表的名称 + 字符Dts。例如:采购定单的名称为:PO_Order,则采购定单的明细表为:PO_OrderDts 对于有主明细的表来说,明细表必须包含两个字段:主表关键字、SN,SN字段的类型为int 型,目的为与主表关键字联合组成明细表的关键字,以及标示明细记录的先后顺序,如1,2,3……。

7)表必须填写描述信息 7)后台表名尽量与前台表名相同,后台独有的表应以_b作为后缀。如r_gggd_b 1.2表字段命名规范 数据库字段的命名必须遵循以下规范: 1)字段名称一般采用名词或动宾短语,且字段名为小写。 2)采用有意义的字段名。字段的名称必须是易于理解,能表达字段功能的英文单词或缩写英文单词,单词首字母必须大写,一般不超过三个英文单词。例如:人员信息表中的电话号码可命名为:Telephone或Tel。产品明细表中的产品名称可用ProductName表示。(推荐一般用完整的英文单词)。 3)系统中所有属于内码字段(仅用于标示唯一性和程序内部用到的标示性字段),名称取为:“ID”,采用整型或长整型数,具体根据可能的数据量确定,增加记录时取最大值加1,该字段通常为主关键字。 4)系统中属于是业务范围内的编号的字段,其代表一定的业务信息,比如资料信息和单据的编号,这样的字段建议命名为:“Code”,其数据类型为varchar,该字段需加唯一索引。 5)在命名表的列时,不要重复表的名称;例如,在名为 Employee 的表中避免使用名为EmployeeLastName 的字段。 5)不要在列的名称中包含数据类型。

MYSQL数据库命名及设计规范

MYSQL数据库命名及设计规范 1.设计原则 1)标准化和规范化 数据的标准化有助于消除数据库中的数据冗余。标准化有好几种形式,但Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说,遵守3NF标准的数据库的表设计原则是:“One Fact in One Place”即某个表只包括其本身基本的属性,当不是它们本身所具有的属性时需进行分解。表之间的关系通过外键相连接。它具有以下特点:有一组表专门存放通过键连接起来的关联数据。 举例:某个存放客户及其有关定单的3NF数据库就可能有两个表:Customer和Order。Order表不包含定单关联客户的任何信息,但表内会存放一个键值,该键指向Customer表里包含该客户信息的那一行。 事实上,为了效率的缘故,对表不进行标准化有时也是必要的。 2)数据驱动 采用数据驱动而非硬编码的方式,许多策略变更和维护都会方便得多,大大增强系统的灵活性和扩展性。 举例,假如用户界面要访问外部数据源(文件、XML文档、其他数据库等),不妨把相应的连接和路径信息存储在用户界面支持表里。还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那么产生工作流的数据也可以存放在数据库里。角色权限管理也可以通过数据驱动来完成。事实上,如果过程是数据驱动的,你就可以把相当大的责任推给用户,由用户来维护自己的工作流过程。 3)考虑各种变化 在设计数据库的时候考虑到哪些数据字段将来可能会发生变更。 举例,姓氏就是如此(注意是西方人的姓氏,比如女性结婚后从夫姓等)。所以,在建立系统存储客户信息时,在单独的一个数据表里存储姓氏字段,而且还附加起始日和终止日等字段,这样就可以跟踪这一数据条目的变化。 2.数据库涉及字符规范 采用26个英文字母(区分大小写)和0-9这十个自然数,加上下划线'_'组成,共63个字符.不能出现其他字符(注释除外). 注意事项: 1)以上命名都不得超过30个字符的系统限制.变量名的长度限制为29(不包括标识字符@). 2)数据对象、变量的命名都采用英文字符,禁止使用中文命名.绝对不要在对象名的字符之间留空格. 3)小心保留词,要保证你的字段名没有和保留词、数据库系统或者常用访问方法冲突 5)保持字段名和类型的一致性,在命名字段并为其指定数据类型的时候一定要保证一致性.假如数据类型在一个表里是整数,那在另一个表里可就别变成字符

相关文档
最新文档