数据库学习笔记

CREATE TABLE dbo.po_details (
OrderID int NOT NULL, ProductID int NOT NULL, UnitPrice money NOT NULL DEFAULT (0),
Quantity smallint NOT NULL DEFAULT (1), Discount real NOT NULL DEFAULT (0) ,
CONSTRAINT PK_po_details PRIMARY KEY CLUSTERED (OrderID, ProductID)
CONSTRAINT FK_po_details_Orders FOREIGN KEY (OrderID) REFERENCES dbo.Orders
CONSTRAINT FK_po_details_Products FOREIGN KEY (ProductID) REFERENCES dbo.Products ) ;
CREATE INDEX OrderID ON dbo.po_details (OrderID ) ;
CREATE INDEX Orderspo_details ON dbo.po_details (OrderID ) ;
CREATE INDEX ProductID ON dbo.po_details (ProductID ) ;
CREATE INDEX Productspo_details ON dbo.po_details (ProductID ) ;
 
 
 
create table dbo.po_orders
(
orderid int not null,
unitprice money default (0),
quantity smallint default(1),
discount real default(0.0),
constraint pk_po_orders primary key clustered (orderid)
)
 
create table dbo.po_products
(
productid int not null,
unitprice money default (0),
quantity smallint default(1),
discount real default(0.0),
constraint pk_po_products primary key clustered (productid)
)
 

create table dbo.po_details
(
orderid int not null,
productid int not null,
unitprice money default (0),
quantity smallint default(1),
discount real default(0.0)
)
alter  table po_details
add constraint pk_po_details primary key clustered (orderid,productid)
 
alter  table po_details
add constraint fk_po_details_order foreign key (orderid)references dbo.orders
alter  table po_details
add constraint fk_po_details_products foreign key (productid)references dbo.products
 

以上创建的表
下面两行是设两个外建,但前提是要有dbo.orders dbo.products这两个表,
而设的这两个orderid,productid刚一定要是dbo.orders dbo.products这两个表的主建
 

sql
 
6.1select sql
sytan:
select columnname1,columnname1...
from tablename
 
sample:
select customerid,city,companyname,contactname
from customers
where city='london'
order by customerid desc
 
select customerid,city,companyname,contactname
from customers
where city='london'
order by customerid asc
 
study no1
select customerid,companyname,city,region
from customers
where city='london'
order by customerid desc ,companyname asc
 

select '2' as cat, avg(unitprice) as avgprice,avg(unitsinstock) as avgqty
from products
where categoryid=1
 
select
categoryid,
productname,
unitprice,
unitsinstock,
unitprice * unitsinstock as amount
from products
order by categoryid
 

select orderid,customerid,
year(orderdate) as years,
month(orderdate) as months,
day(orderdate)as dates
from orders
 
.distinct
select categoryid
from products
 

select distinct categoryid
from products
where categoryid  between 1 and 5/where categoryid  between '1' and '5'
 

select distinct categoryid
from products
where categoryid in (1,3,5)
 

select distinct categoryid
from products
where categoryid not between 1 and 5
 
select productname
from products
where productname like 'c%'
 
select productname
from products
where productname like '%s'
 
select productname
from products
where productname like '%f%'
 
select productname
from products
where productname in ('chai')
 

.not/is null
select count(*) as trow
from  customers
where region is null
 
select count(*) as trow
from  customers
91 rows
 
select count(*) as trow
from  customers
where region is null
61 rows
 
select count(*) as trow
from  customers
where region is not null
 
30 rows
 
multy table select
parenet:products
childer:orders
 
select count(*)
from products,order_detail
where products.productid=order_detail.productid
 
 
 
select distinct products.categoryid,categories.categoryname
from products,categories
where products.categoryid=categories.categoryid
order by products.categoryid
 

select sum(unitsinstock)
from products
group by categoryid
 

select *
from products
where (((unitsinstock>20)and (productname between 'chai'and 'pavlova'))
or categoryid in ('1'))and productname like '%an%'
 

insert into shippers (companyname,phone)
values ('dddd','(053) 555-5268')
 

update shippers set companyname='speedy express'
where companyname='ccty'and phone ='(050) 555-5455';
 

create table sum(name char(25),nianling int)
 
create table tb_userlist(
id int not null,
age int not null check(age >=1 and age <=200),
userid char(10) not null default '',
username char(20) default '',
modifydate char(20) not null default (getdate()),
)
alter table tb_userlist add primary key(id)
 

组合查询结果(union)一个或多个查询结果放到一个表里
 
注意:两个表必须包含同样数目字段
      第一个表里与第二个表里的数据类型一定要相同
      两个表里不能用ORDER BY子句排列
 
select  userid,username
from db_userorder1
where username=23
union
select  userid,username
from db_userorder
where username='123'
 
select  userid,username
from db_userorder1
where username=23
union  all                出现两个重复的结果
select  userid,username
from db_userorder
where username='123'
 
select  userid,username
from db_userorder1
where username=23
union
select  userid,username
from db_userorder
where username='123'
order by 1,2              没有多大的意思
 

select *
from a
union(select*
      from b
      union
      select*
      from c
)
多个union的重复查询
 

create table tb_namelist1
(aa int primary key ,
bb char(10),
cc int ,
dd char(20),
ss datetime default (getdate()))
 
create table tb_namelist2
(aa int primary key ,
bb char(10),
cc int ,
dd char(20),
ss char(20) default (getdate()))
 
insert into table_name(name,no,username)
vlaues('dfdf',11,'ddddd')(主健不用高值)
 
insert into table_name
vlaues('dfdf',11,'ddddd')(主健不用高值)
 

delete  
from table_name
where name='ddd'
 

update 的使用
 
update tb_namelist1
set cc=10000
where cc='3'
 
update tb_namelist1
set cc=cc+1
3 row updated.
 
权限的设置
 
grant/revoke insert on tb_namelist1
to li(用户)
 
grant/revoke all on tb_namelist1
to li
 
grant/revoke update,select,delete,alter on tb_namelist1
to li
 

sp_addlogin 'test','test','db'
 
1 >
 
创建数据库登陆用户 如 “用户名”,‘密码’,‘数据库名’
go
sp_addsrvrolemember 'test','sysadmin'
分配权限
go
sp_addrolemember 'db_owner','test'
 
增加数据库角色 
 
SQL Server用户aa添加到当前数据库中的  test角色。 
  EXEC  sp_addrolemember  'test',  'aa' 
 
数据类型
 
integer 整数类型                            
        数量 年龄 编号 订单号
 
decimal number 小数                     
        分数部分 必须精确的数  比率和百分号
 
floating point number 浮点数               
        重量,距离 小数更大的范围(会出现四舍五入的错误)
 
fixed-length character string 固定长度字符串       
        人名,公司名,通讯地址 描述 
 
variable-length character string  变长字符串  
        每行长度可变成最大长度
 
money amount资金数额                        
        money与currency类型,表现出小数和浮点数
 
date and time 日期和时间
        时间.日期.时间间隔..etc 计算的组合sql2里的标准 date,time,timestamp和interval数据类型的
精确规范。时区(time zooe)时间精度(10秒,100秒)。
                         
boolean data 布尔数据
        支持逻辑值作为显示类型(true或false),还有逻辑运算(and/or,比较)。
 
long text 长文本
        可以存储整个文本,产品说明,技术文本,简历。交互式查询和查找中,DBMS通常限制这些字段的使用。
 
unstructured byte stream 无结构字节流
        存储压缩视频图像,可执行代码,其他类型的无结婚数据。
 
non-roman character 非罗马字符
        支持其它亚洲和阿拉伯字符
 
 
 
七章    多表查询(连接)
 
1.  通过匹配相关字段的内容来形成一对一对的记录的过程连接表。
   
    1>用记录选择标准进行连接
    2>多个匹配字段
     select order_num,amount,description
     from orders,products
     where mfr=mfr_id
           and products=product_id
    3>三个或更多表的查询
 
2.  其它等连接
    1>匹配主键和外键字的连接总是创建一对多的父/子关系。
    2>至少一个表中的匹配字段对于表的所以有记录有唯一值,那么其它连接可以生成一对多的关系。
    3>通常,在任意匹配字段上的连接生成多对多关系。
 
 
3   不等连接
     select name,quota,city,target
     from salesreps,offices
     where quota>/<target 使用符号来表达不等连接。
 
4   SQL对多表查询要考虑的因素
    1>在多表查询中有时需要限定段名,用以消除含糊的字段引用。
     select city,sales,name
     from salesreps,offices
     where rep_office=office
error:ambiguous column name'sales'系统不知道你要的是salesreps表,还是offices
的seles
 
改正如下,
     select city,offices.sales,name
     from salesreps,offices
     where rep_office=office
 
    2>对多查询而言,选择所有字段(select*)具有特殊的意义
    3>可以使用自连接来创建把一个表关联到其自身的多表查询
     select emps.name,mgrs,name
     from emps, mgrs
     where emps.manager=mgrs.empl_num
 
 表emps 与表mgrs是相同的一个表,只是表名不一样。
虚构的重复表,方法来把一个表和它自身连接起来。
 
    4>FROM子句中可以使用表的别名来简化限定字段名,并允许自连接中的明确的字段引用。
    给表启一个别名,在FROM 一定要注名
    select s.name,quota,o.number
    from salesreps s,offices o
    where s.name=o.name
 
5   多表查询的性能
6   连接的结构 
     1>表的乘积
    连接是对两个表的数据的通用组合(称为笛卡儿积,或积)
     2>多表查询的处理原则
    查询结果一个集的过程
7   外连接
  是一个信息保留连接,有你想查到的也结果,也会保留空的也会保留。
    select*
    from girls,boys
    where girls.city *=* boys.city
   1.按正常匹配字段生成两个表的连接。
   2.对于第一个表中不被第二个表匹配的任何记录,查询结果只是第一个表的字段的值。假定第二个表的字段都会null值.
   3.对于第二个表中不被第一个表匹配的任何记录,查询结果只是第二个表的字段的值。假定第一个表的字段都会null值.
   4.所得的结果表是两个表的外连接。
 
  1>左外连接和右外连接
   左外连接:select*
             from girls,boys
             where girls.city *=boys.city
   右外连接:select*
             from girls,boys
             where girls.city =* boys.city
 
  2>外连接的符号是: *
 
如果是多表外连接  tel1 outer-join tel2 outer-join tel3
 
8    连接和SQL2标准
     sql的标准制订的规范放到FROM子句中,并使用了准确的语法。
  
    1>SQL2中的内连接
    select *
    from girls inner join boys
    on girls.city=boy.city
    using子句指定了用逗号分隔的匹配字段名列表,在个匹配字段在两个表中必须是相同的,
 它等价于ON,不过用ON可以在两个表里出现不同的两个匹配字段。
    select *
    from girls inner join boys
    using(city,age)
 如果指定了natural关健字,那么连接说明中不能使用on或using子句。
    SELECT*
    FROM GIRLS NATURAL INNER JOIN BOYS
 
    2>SQL2中的外连接
    全外连接 
    SELECT *
    FROM GIRLS FULL OUTER JOIN BOYS
    ON GIRLS.CITY=BOY.CITY
    OUTER 字句可以省略不写。
   
    3>SQL2中的交叉连接和合并接连
     两个表的完全乘积
     SELECT *
     FROM GIRLS CROSS JOIN BOYS
     等于 SELECT *
     RROM GIRLS,BOYS
     合并连接,使用 UNION
     SELECT *
     FROM GIRLS
     UNION JOIN BOYS
  -----------------------------------------------------------------------------
     左外连接 left join              合并连接                 右外连接 right join
      匹配的                         匹配的                    匹配的
   TBL1 ROWS                       TBL1/TBL2                   TBL2 ROWS
  WITH NULL VALUES                 ROW PAIRS                 WITH NULL VALUES                   
  FOR TBL2 COLUMNS                 内连接                     FOR TBL1 COLUMNS
     未匹配的                        未匹配的                   未匹配的
   TBL1 ROWS                       TBL1/TBL2                   TBL2 ROWS
  WITH NULL VALUES                 ROW PAIRS                 WITH NULL VALUES                   
  FOR TBL2 COLUMNS                 交叉连接                   FOR TBL1 COLUMNS
 TBL1,NULL值扩展的               所以有TBL1*TBL2对            TBL2,NULL值扩展的
 
  4>SQL2中的多表连接
 
  第八章 汇总查询
 
  8.1 字段函数
      ` SUM()计算字段的总和
        AVG()计算字段的平均值
        MIN()查找字段中的最小值
        COUNT()计算字段中值的数目
        COUNT(*)计算查询结果的记录数
  GROUP BY 与  HAVING 子句支持这些汇总数据的请求。
 
  8.1.2 NULL的值和字段函数
     SELECT COUNT(*),COUNT(SALES),COUNT(QUOTA)
     FROM SALESREPS
     结果COUNT(*) 10,COUNT(SALES)10 ,COUNT(QUOTA)9
   因QUOTA 有一个NULL值,所以只返回9个。
 
  注意:1>如果字段中任何数据值是NULL,那么计算函数时就会将他们忽略。
        2>如果字段中每个数据项都是NULL,那么除COUNT()返回0值以外,都返回NULL。
        3>如字段是空的,那么除COUNT()返回0值以外,都返回NULL。
        4>COUNT(*)记录时,不理会字段里是否NULL值存在都会返回0
 
  8.1.3 清除重复记录(DISTINCT)
        SELECT COUNT(DISTINCT TITLE)
        FROM SALESPEPS
 
  8.1.4 分组查询(GROUP BY 子句)
        SELECT ERP,AVG(AMOUNT)
        FROM ORDERS
        GROUP BY ERP
  8.1.5 多个分组查询
        SELECT ERP ,CUST,SUM(AMOUNT)
        FROM ORDERS
        GROUP BY CUST,ERP
        ORDER BY CUST,ERP
      注意:不能从一个查询中同时获得详细和汇总查询结果。
     COMPUTE子句可以排除这个难点,它可以计算小计和子小计。
        SELECT ERP,CUST,AMOUNT
        FROM ORDERS
        ORDER BY ERP,CUST
        COMPUTE SUM(AMOUNT)BY ERP,CUST
        COMPUTE SUM(AMOUNT),AVG(AMOUNT)BY ERP
  8.2.1 分组查询的限制
        一个常量。
        一个字段函数,此函数生成一个值,值为汇总组中的记录。
        一个分组字段,这个分组字段在组中的每个记录有同样的值。
        涉及上述各项组合的表达式。
  8.2.3 分组字段中的NULL值
        如果两条记录在同一分组字段有NULL,并在其它非NULL分组字段有同样地的
       值,那么它们就放到同一记录组中。
  8.3   分组搜索条件(HAVING 子句)
       HAVING=WHERE, HAVING子句与GROUP BY 子句一起使用。HAVING 单独使用就只表示一个查询组。
      
       SELECT ERP,AVG(AMOUNT)            语句运行每三步,
       FROM ORDERS                          语句运行每三步,
       GROUP BY ERP                         语句运行每一步,
       HAVING SUM(AMOUNT)>30000           语句运行每二步,
    
 九章  子查询和查询表达式
 
  9.1   什么是子查询
        子查询是一个查询中的查询,出现在WHERE、HAVING 子句里的一个小子查询搜索条件内。
  9.1.2  WHERE 字句中的子查询
        SELECT NAME
        FROM SALESREPS
        WHERE QUOTA>(0.1*(SELECT SUM(TARGET)FROM OFFICES))
  9.1.3  外部引用
        当DBMS检查子查询中的搜索条件时,外部引用中的字段值从主查询检测的当前记录中提取。
 
  9.2   子查询搜索条件
          
  9.2.1 子查询比较测试(=,<>,<,<=,>,>=)
         把一个表达式的值与一个子查询的生成的值做比较。
  9.2.2 组成员测试 (IN)
        检查一个表达式的值是否匹配由一个子查询生成的一组值中的一个。
  9.2.3 存在测试(EXISTS)
        测试子查询是否生成任何查询结果记录.
        SELECT QUOTA
        FROM SALESREPS
        WHERE EXISTS (0.1*(SELECT SUM(TARGET)FROM OFFICES))
  9.2.4 限定测试(ANY和ALL)
        检查一个表达式的值一由一个子查询生成的一组值中的每一个比较。
 
9.3    子查询和连接
       子查询也可以写成多表查询或连接
       第一种:SELECT NAME,AGE
               FROM SALESREPS
               WHERE ERP_OFFICE IN(SELECT OFFICE
                             FROM OFFICES
                             WHERE REGION=‘WESTERN’)
       第二种: SELECT NAME,AGE
               FROM SALESREPS,OFFICE
               WHERE REP_OFFICE=OFFICE
               AND REGION='WESTERN'
       两种结果是一样的,第一种是运用了子查询,第二种是连接
 
9.4    嵌套的子查询
      
       主查询与子查询是二级查询,如果出现更多的子查询就会是三级查询
       如:SELECT *
           FROM TABLE1
           WHERE ID IN(SELECT *
                         FROM TABLE2
                         WHERE PRODUCT IN(SELECT *
                                           FROM TABLE3
                                           WHERE NAME IN))
 
9.5    关联子查询
      
        对多子查询来说主查询的结果,子查询也会生成对应的一个或是一组结果。
        所以在关联的子查询的过程中是用来主查询与子查询做对比。
 
9.6    HAVING子句中的子查询
      
       当查询结果是一组的时候或是主查询一组数据与子查询的一组数据做对比时就会用HAVING
       称为记录组
 
  前面几章的总结:在SELECT子句中的字段选择,在FORM子句中的多表连接,WHERE子句中的记录选择条件。
  HAVING、GROUP BY子句中的汇总查询
 
9.8   SQL2 中的高级查询
 
      `1在查询中没有决策制度功能
      `2子查询的限制使用
        SELECT OFFICE
        FROM OFFICES
        WHERE(SELECT SUM(QUOTA)
                FROM SALESREPS
                WHERE ERP_OFFICE=OFFICE)> TARGET
  这个是不合法的SQL1语句,不等号要反过来,
  因WHERE子句中比较测试在于右过。
        SELECT OFFICE
        FROM OFFICES
        WHERE TARGET>(SELECT SUM(QUOTA)
                FROM SALESREPS
                WHERE ERP_OFFICE=OFFICE)
这样是合法的
 
      `3受限制的记录表达式
       
      `4受限制的表的表达式
      
 
9.8.1  标量值表达式(SQL2)
 
      1 CAST 表达式
 
       用途之一处理数据库里的NULL值
      在SQL1 转换来自一个数据库表的数据,其中在这个表中字段定义了错误的数据类型。
             转换数据类型,不为宿主编程语言支持的DBMS支持.
             清除在两个不同的表中数据类型之间的差别。
 
         SELECT PRODUCT,QTY AMOUNT
         FROM    ORDERS
         WHERE CUST=CAST‘2107’AS INTEGER
 
      CAST 表达式
      在SQL2 中的查询是按,第一个搜索条件为正解的,就是CASE表达式的值,如第一个搜索条件不正解就会到第二个搜索条件。
      如此下去。
     
       SELECT COMPANY,CASE WHEN CREDIT_LIMIT>6000 THEN 'A'
                            WHEN CREDIT_LIMIT>3000 THEN 'B'
                            ELSE 'C'
          FROM CUSTOMERS
    
      2  COALESCE 表达式(SQL2)
 
       检查是否有NULL如有就会向下查询,如没有就会变成表达式的值
 
       SELECT NAME,COALESCE(QUOTA,SALES,0.00)              
        FROM SALESREPS
      
      3  NULLIF表达式(SQL2)
         它检测两个值是否相等,如相同就会生成一个NULL
 
        SELECT CITY,SUM(SALES)
        FROM OFFICES,SALESREPS
        WHERE OFFICE=(NULLIF REP_OFFICE,0)
        GROUP BY CITY
 
9.8.2   记录值的表达式(SQL2)
      
      `1 记录值的结构
      `2 记录值子查询
      `3 记录值做比较
 
9.8.3   表值表达式
      `1 表的结构
      `2 表值子查询
          查询规范
 
9.8.4 查询表达式
    
     连接(JOIN) 交叉连接,处连接,内连接,所有类型的外连接 ,
        
     并(UNION)  合并两个兼容表的记录
    
     差(DIFFERENCE) 像两个表的减法一样
 
     交(INTERSECT)包含出现在两个表中的记录
 

            第三部分
 
                               更新数据
 
      第十章         数据库更新
 
 
 
 
 
 
 
 
 
 
 
 
 

      第十一章       数据库完整性
   
 
 
 
 
 
    11.6.1 断言
         
   因为断言是数据库中的一个对象(如表或字段)所以有必须有一个名字,当违反的时候DBMS出错。
  
   例如: 保证客户订单的资金总量不超过他们的信用额度
 
       CREATE ASSERTRON credit_orders
            CHECK (CUSTOMER.CREDIT_LIMIT <=
                       SELECT SUM (ORDERS.AMOUNT)
                           FROM ORDERS
                        WHERE ORDERS.CUST = CUSTOMER.CUST_NUM)
 
    11.6.2 SQL2 约束类型
    
           NOT NULL(非空)约束             约束仅出现在字段约束中
 
           PRIMARY KEY(主键字)约束        出现在字段或是表约束中
 
           UNIQUE(惟一性)约束             可以出现在字段约束或表约束中。
      
           FOREIGN KEY (外键字)约束       可以出现在字段约束或表约束中  
 
           CHECK(检验)约束                可以出现在字段约束或表约束中,它也是惟一的形成域或断言定义的约束。
   
   11.6.3 延期约束检验
 
          当服务器对数据库的更新必须立即执行,以保持数据的一致性,延期约束检验就很重要。
       
          例如:  保证销售点的定额目标精确地与各个销售人员的销售定额总和相等
                
           CREATE ASSERTION QUOTA _TOTALS
             CHECK ((OFFICES.QUOTA = SUM(SALESREPS.QUOTA))AND
                       (SALSREPS.ERP_OFFICE = OFFICES.OFFICE))
 
           如果在一个表中用INSERT 而不更新另一个表,断言不为TURE。 或 UPDATE一个表时,另一个表不插入这个数据
           断言也不为TURE.
          
    所以: DEFERRABLE(可延期执行)约束                
                
                   INTIALLY IMMEDIATE(初始立即执行)约束     它将立即检验每一个SQL语句  
  
                   INITIALLY DEFERRDE (初始延时执行)约束     被延期检验,直到事务结束。
          
          NOT DEFERRABLE (不可延期执行)约束          不能被延期检验的约束,如主键字约束,惟一性约束 等。
 
         
          例如:  CREATE ASSERTION QUOTA _TOTALS
                     CHECK ((OFFICES.QUOTA = SUM(SALESREPS.QUOTA))AND
                       (SALSREPS.ERP_OFFICE = OFFICES.OFFICE))
                      DEFERRABLE INITIALLY IMMEDIATE
 
                         
        手工设置约束为IMMEDIATE模式
 
             SET CONSTRAINTS QUOTA_TOTALS IMMEDIATE
        也可以用逗号分隔的列表把几种不同的约束设置为同样的模式。
             SET CONSTRAINTS QUOTA_TOTALS,REP_TOTALS IMMEDIATE
        最后,可以用单独一条语句为所有约束设置处理模式。
             SET CONSTRAINTS ALL DEFERRED
 

  11.7 商业规则
      
       1. 不允许客户给出超出客户信用额度的订单。
       2. 无论何时要指定某个客户的信用度高于50000美元,必须通知销售副总裁。
       3. 订单登记之后,仅可以保留半年,订单超过半年时,必须被撤销和重新输入。
       4. 无论何时获得一份新订单,获得订单的人员和人员工作的销售点的SALES字段,应按订单的订购数量而增加。
       5. 无论何时获得一份新订单,订单上产品的QTY_ON_HAND字段应该按产品订购的数量而减小。
     
     商业规则缺点
 
       1. 重复工作    几个不同的程序处理各种对ORDERS表的更新,它们中的每一个必须包含实施与ORDERS更新有关的规则代码。
       2. 缺乏一致性  几个程序员对某个表做更新,它们会实施规则,但方式会有所不同。
       3. 维护问题    如修改商业规则,程序员必须识别每个实施规则的程序,然后定位代码并正确修改它。
       4. 复杂性      有许多规则要记住。
 
    11.7.1  什么是触发器
 
        例如:当添加一个新订单到ORDERS表时,下面两个对数据库的修改也应该发生。
 
              1. 获得订单的销售人员的SALES 字段应该根据订单的数量面增加。
              2. 被订购的产品的QTY_ON_HAND数量应该根据订购数量而减少。
 
        
        用SQL SERVER触发器定义
 
              CREATE TRIGGER NEWORDER------------NEWORDER 新表名
                 ON ORDERS
                 FOR INSERT
              AS UPDATE SALSREPS
                  SET SALES = SALES + INSERTED.AMOUNT
                  FROM SALESREPS,INSERTED
                  WHERE SALESREPS.EMPL_NUM = INSERTED.ERP
                 UPDATE PRODUCTS
                   SET QTY_ON_HAND = QTY_ON_HAND - INSERTED.QTY
                   FROM FRODUCTS,INSERTED
                   WHERE PRODUCTS.MFR_ID = INSERTED.MFR
                    AND PRODUCTS.PRODUCTS_ID = INSERTED.PRODUCT
  
         用DB2语法定义
 
                
             CREATE TRIGGER NEWORDER
                 AFTER INSERT ON ORDERS
               REFERENCING NEW AS NEW_ORD ----------------NEW_ORDG 一个表的另名
                FOR EACH ROW MODE DB2 SQL
                   BEGIN ATOMIC  -------------------------
                 UPDATE SALSREPS
                  SET SALES = SALES + NEW_ORD.AMOUNT
                  WHERE SALESREPS.EMPL_NUM = NEW_ORD.ERP;
                  UPDATE PRODUCTS
                    SET QTY_ON_HAND = QTY_ON_HAND - NEW_ORD.QTY
                   WHERE PRODUCTS.MFR_ID = NEW_ORD.MFR;
                    AND PRODUCTS.PRODUCTS_ID = NEW_ORD.PRODUCT
                    END
                  
    11.7.2 触发器与引用完整性
 
          触发器也可以被用来提供引用完整性的扩展形式。
        
          1 引用完整性的的触发器
            更新失败时
           create trigger erp_update
            on salesreps
               for insert,update
                 as if ((select count(*)
                            from office ,inserted
                           where offices.office=inserted.erp_office)=0)
                begin
                     print"invalid office number specified"
                     rollback transction
                end
          2 db2最初通过CASCADE级联更新,如主健字值改变,则不运动支持层叠更新。
       但SQL SERVER 的触发器可以完成层叠更新。
        例如:层叠更新OFFICE 表中的OFFICE字段为SALESREPS表的REP_OFFICE 字段  
 
          create trigger change_erp_office
               on offices
              for update
               as if update(office)
               begin
                    update salesreps
                    set salesreps.erp_office = inserted.office
                    from salesreps,inserted,deleted
                    where salesreps.erp_office = deleted.office
          
 
    11.7.3 触发器的优缺点
           
          
          1. 数据库复杂性:触发器编程使任务变的复杂
          2. 隐藏规则:    规则隐藏在数据库里,更新时,就会不在程序员的控制下产生大量的数据库动作。
          3. 隐藏性能的暗示: 用存储在数据库里的触发器,执行SQL语句的结果不在为程序员完全可见。
 
    禁用或开启触发器
           语法:alter table <表名> enable/disable trigger 触发器名
 
           例如:alter table tb_hr_gz enable/disable trigger tg_tb_hr_gz
           
             
 
 
 
                        第十二章  事务处理
 
   
 
       
 
         如:增加一个订单:
             1.查询PRODUCTS表,确定库中有相应产品
             2.插入订单到ORDERS表
             3.更新PRODUCTS表,从现有产品数量减去已订购的数量。
             4.更新SALESREPS表,把订单上所标的产品订购数量添加到取得订单的销售人员的销售总量中。
             5.更新OFFICES表,增加订单上所标的产品订购数量到销售人员工作的销售点的销售总量中。
          
             取消订单
 
             1.从ORDERS表中删除订单
             2.插入订单到ORDERS表
             3.更新SALESREPS表,把订单上所标的产品订购数量得到取得订单的销售人员的销售总量中删除。
             4.更新OFFICES表,删除订单上所标的产品订购数量到销售人员工作的销售点的销售总量中
   
    12.1 什么是事务
        
         事务(transaction)是一条或多条SQL语句序列,它们组合在一起形成一个逻辑工作单元。
   按先后顺序完成任务。
 
    12.1.1
         COMMIT(提交)  COMMIT语句 表示事务成功结束
         ROLLBACK(回滚) ROLLBACK语句 表示事务没有成功结束
      例如:编号113051的订单量从4改为10 总销售额从1458改为3550 订单上的产品是QAS-XK47减压器,
           工作在LOS ANGELES 销售编号为21 的LARRY FITCH 雇员编号为108
          
         UPDATE ORDERS
           SET QTY = 10,AMOUNT =3550.00
         WHERE ORDER_NR =113051
         UPDATE SALESREPS
           SET SALES = SALES -1458.00+3350.00
         WHERE EMPL_NUM = 108
         UPDATE OFFICES
           SET SALES = SALES -1458.00+3350.00
         WHERE OFFICE= 21
         UPDATE PRODUCTS
           SET QTY_ON_HAND = QTY_ON_HAND + 4 -10
         WHERE MFR_ID = 'QSA'
         AND PRODUCT_ID='XK47'
        .......确认最后一个关于客户的修改写成........
          COMMIT WORK
       
       对比, 假如这个用户错误的输入了产品编号 
         
         UPDATE ORDERS
           SET QTY = 10,AMOUNT =3550.00
         WHERE ORDER_NR =113051
         UPDATE SALESREPS
           SET SALES = SALES -1458.00+3350.00
         WHERE EMPL_NUM = 108
         UPDATE OFFICES
           SET SALES = SALES -1458.00+3350.00
         WHERE OFFICE= 21
         UPDATE PRODUCTS
           SET QTY_ON_HAND = QTY_ON_HAND + 4 -10
         WHERE MFR_ID = 'QAS'
         AND PRODUCT_ID='XK47'
        .......噢!生产厂家是“QSA”不是“QAS”........
          ROLLBACK WORK
  
      12.1.2 ANSI/ISO 事务模型
        
         COMMIT(提交)  COMMIT语句 表示事务成功结束,它使数据库永久被修改,COMMIT后立即开始下个新事务
         ROLLBACK(回滚) ROLLBACK语句 表示事务没有成功结束,回腿对数据库的修改,ROLLBACK 后立即开始下个新事务
         SUCCESSFUL PROGRAM TERMAINATION(成功地终止程序)事务成功结束,但之后没有新事务。
         ABNORMAL PRGRAM TERMINATION (非正常地终止程序) 务没有成功结束,但之后没有新事务。
     
      12.1.3 其它事务模型
        
          SYBASE 作用的TRANSACT-SQL方言包括4条事务处理语句
 
           BEGIN TRANSACTION(开始事务)表示事务开始。ANSI/ISO模型暗示在前一个事务结束,后个事务开始。而SYBASE需要
                                        一条明确的语句来开始一个事务。        
           COMMIT TRANSACTION(提交事务) 事务成功结束,与ANSI/ISO模型一样对数据库永久被修改,但是,瓣的事务不会自动开始。
           SAVE TRANSACTION (保存事务)  在事务的中间建立一个保存点(SAVEPOINT),SYBASE 在事务中的当前点保存数据库的状态,
                                          并且给保存状态赋一个保存点的名,该保存点名在语句中指定。
           ROLLBACK TRANSACTION(回滚事务)该事务有两个角色,如保存点在ROLLBACK语句中命名,SYBASE自保存点撤销所做的数据修改
                                           回到保存点(SAVE TRANSACTION),如没有命名保存点,ROLLBACE反回到BEGIN TRANSACTION
                                           开始,撤销所以对数据的修改。
         
    12.2 事务的内幕
         
         
    12.3 事务和多用户处
      
      12.3.1 丢失更新的问题
      12.3.2 未提交数据的问题
      12.3.3 不一致数据的问题
      12.3.4 虚幻插入的问题
      12.3.5 并发事务 
 
 

    12.4 锁定
 
       12.4.1 锁定级别
       12.4.2 共享独占锁
       12.4.3 死锁 DEADLOCK
       12.4.4 高级锁定技术
           明锁  
           绝缘锁   
           锁定参数  
              锁的尺寸  锁定的数量    扩大锁   锁定超时
           独占模式   
           共享模式
          
    12.5 版本化
     
 

                                        第四部分
 
            第十三章 创建数据库
 
   13.1 数据定义语言
       
       DATA DEFINITION LANGUAGE,DDL
    能够知道:
       1.定义和创建新表。
       2.删除不再需要的表。
       3.修改已有表的定义。
       4.定义数据的虚表(视图)。
       5.建立数据库安全控制。
       6.建立索引,以便可以快速访问表。
       7.用DBMS 控制数据的物理存储。
   
   13.2 表定义
   
     13.2.1 创建表
     
       字段定义
 
          字段名:表中的字段必有要有一个名字,其它表里可以相同
          数据类型: VARCHAR、DECIMAL 需要附加数据长度和小数点的位置,放圆括号里面。
          要求的数据: 是为NULL或NOT NULL
          默认值:     当INSERT时没有指定字段值时,这个字段使用默认值。
     
       主键字和外键字
           FOREIGN KEY 子句指明表中的外键字和表与数据库中另一个(父表)的关系,子句指明:
          1.形成外键字的字段或字段组,所有这些字段都是所创建的表的字段。
          2.被外键字引用的表,这是关系中的父表,被定义的表是子表。
          3.关系的可选名,在SQL数据操作语言中都不使用这个名字中,但是它可以出现在错误信息中,如果以后想要停止
            使用外键字,要用到该名字。
          4.当将它与父表中的记录匹配时,DBMS怎么处理外键字的一个或多个字段中的NULL值。
          5.关系的可选的删除规则
          6.关系的可选更新规则
          7.可选的检验约束它限制表中的数据,以便它的各个记录符合指定的搜索条件。
  
 
 

你可能感兴趣的:(数据库学习笔记)