sql--复习

View Code
  1 USE master
  2 GO
  3  
  4 EXEC xp_cmdshell 'mkdir d:\bank', NO_OUTPUT  
  5  
  6 --检验数据库是否存在,如果为真,删除此数据库--
  7 IF exists(SELECT * FROM sysdatabases WHERE name='bankDB')
  8   DROP DATABASE bankDB
  9 GO
 10 --创建建库bankDB
 11 CREATE DATABASE bankDB
 12  ON
 13  (
 14   NAME='bankDB_data',
 15   FILENAME='d:\bank\bankDB_data.mdf',
 16   SIZE=3mb,
 17   FILEGROWTH=15%
 18  )
 19  LOG ON
 20  (
 21   NAME= 'bankDB_log',
 22   FILENAME='d:\bank\bankDB_log.ldf',
 23   SIZE=3mb,
 24   FILEGROWTH=15%
 25  )
 26  
 27 GO
 28 /*$$$$$$$$$$$$$建表$$$$$$$$$$$$$$$$$$$$$$$$*/
 29  
 30 USE bankDB
 31 GO
 32  
 33 CREATE TABLE userInfo  --用户信息表
 34 (
 35   customerID INT IDENTITY(1,1),
 36   customerName CHAR(8) NOT NULL,
 37   PID CHAR(18) NOT NULL,
 38   telephone CHAR(13) NOT NULL,
 39   address VARCHAR(50)
 40 )
 41 GO
 42  
 43 CREATE TABLE cardInfo  --银行卡信息表
 44 (
 45   cardID  CHAR(19) NOT NULL,
 46   curType  CHAR(5) NOT NULL,
 47   savingType  CHAR(8) NOT NULL,
 48   openDate  DATETIME NOT NULL,
 49   openMoney  MONEY NOT NULL,
 50   balance  MONEY NOT NULL,
 51   pass CHAR(6) NOT NULL,
 52   IsReportLoss BIT  NOT NULL,
 53   customerID INT NOT NULL
 54 )
 55 GO
 56  
 57 CREATE TABLE transInfo  --交易信息表
 58 (
 59   transDate  DATETIME NOT NULL,
 60   transType  CHAR(4) NOT NULL,
 61   cardID  CHAR(19) NOT NULL,
 62   transMoney  MONEY NOT NULL,
 63   remark  TEXT  
 64 )
 65 GO
 66  
 67 /*$$$$$$$$$$$$$加约束$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
 68 /* userInfo表的约束
 69 customerID  顾客编号    自动编号(标识列),从1开始,主键
 70 customerName    开户名 必填
 71 PID 身份证号    必填,只能是18位或15位,身份证号唯一约束
 72 telephone   联系电话    必填,格式为xxxx-xxxxxxxx或手机号13位
 73 address 居住地址    可选输入
 74 */
 75 ALTER TABLE userInfo
 76   ADD CONSTRAINT PK_customerID PRIMARY KEY(customerID),
 77       CONSTRAINT CK_PID CHECK( len(PID)=18 or len(PID)=15 ),
 78       CONSTRAINT UQ_PID UNIQUE(PID),
 79       CONSTRAINT CK_telephone CHECK( telephone like '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' or telephone like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' or len(telephone)=13 )
 80 GO
 81  
 82 /*cardInfo表的约束
 83 cardID  卡号  必填,主健 , 银行的卡号规则和电话号码一样,一般前8位代表特殊含义,
 84         如某总行某支行等。假定该行要求其营业厅的卡号格式为:1010 3576 xxxx xxx开始
 85 curType 货币  必填,默认为RMB
 86 savingType  存款种类    活期/定活两便/定期
 87 openDate    开户日期    必填,默认为系统当前日期
 88 openMoney   开户金额    必填,不低于1元
 89 balance 余额  必填,不低于1元,否则将销户
 90 pass    密码  必填,6位数字,默认为6个8
 91 IsReportLoss    是否挂失  必填,是/否值,默认为”否”
 92 customerID  顾客编号    必填,表示该卡对应的顾客编号,一位顾客可以办理多张卡
 93 */
 94 ALTER TABLE cardInfo
 95   ADD CONSTRAINT  PK_cardID  PRIMARY KEY(cardID),
 96       CONSTRAINT  CK_cardID  CHECK(cardID LIKE '1010 3576 [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]'),
 97       CONSTRAINT  DF_curType  DEFAULT('RMB') FOR curType,
 98       CONSTRAINT  CK_savingType  CHECK(savingType IN ('活期','定活两便','定期')),
 99       CONSTRAINT  DF_openDate  DEFAULT(getdate()) FOR openDate,
100       CONSTRAINT  CK_openMoney  CHECK(openMoney>=1),
101       CONSTRAINT  CK_balance  CHECK(balance>=1),
102       CONSTRAINT  CK_pass  CHECK(pass LIKE '[0-9][0-9][0-9][0-9][0-9][0-9]'),
103       CONSTRAINT  DF_pass  DEFAULT('888888') FOR pass,
104       CONSTRAINT  DF_IsReportLoss DEFAULT(0) FOR IsReportLoss,
105       CONSTRAINT  FK_customerID FOREIGN KEY(customerID) REFERENCES userInfo(customerID)
106 GO
107  
108 /* transInfo表的约束
109 transType       必填,只能是存入/支取
110 cardID  卡号  必填,外健,可重复索引
111 transMoney  交易金额    必填,大于0
112 transDate   交易日期    必填,默认为系统当前日期
113 remark  备注  可选输入,其他说明
114 */
115  
116 ALTER TABLE transInfo
117   ADD CONSTRAINT  CK_transType  CHECK(transType IN ('存入','支取')),
118       CONSTRAINT  FK_cardID  FOREIGN KEY(cardID) REFERENCES cardInfo(cardID),
119       CONSTRAINT  CK_transMoney  CHECK(transMoney>0),
120       CONSTRAINT  DF_transDATE DEFAULT(getdate()) FOR transDate
121 GO
122  
123 /*$$$$$$$$$$$$$插入测试数据$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
124 /*
125 张三开户,身份证:123456789012345,电话:010-67898978,地址:北京海淀
126    开户金额:1000 活期   卡号:1010 3576 1234 5678
127 李四开户,身份证:321245678912345678,电话:0478-44443333,
128    开户金额: 1  定期 卡号:1010 3576 1212 1134
129 */
130 SET NOCOUNT ON  --不显示受影响的条数信息
131 INSERT INTO userInfo(customerName,PID,telephone,address )
132      VALUES('张三','123456789012345','010-67898978','北京海淀')
133 INSERT INTO cardInfo(cardID,savingType,openMoney,balance,customerID)
134      VALUES('1010 3576 1234 5678','活期',1000,1000,1)
135  
136 INSERT INTO userInfo(customerName,PID,telephone)
137      VALUES('李四','321245678912345678','0478-44443333')
138 INSERT INTO cardInfo(cardID,savingType,openMoney,balance,customerID)
139      VALUES('1010 3576 1212 1134','定期',1,1,2)
140 SELECT * FROM userInfo
141 SELECT * FROM cardInfo
142  
143 GO
144 /*
145 张三的卡号(1010 3576 1234 5678)取款900元,李四的卡号(1010 3576 1212 1134)存款5000元,要求保存交易记录,以便客户查询和银行业务统计。
146 说明:当存钱或取钱(如300元)时候,会往交易信息表(transInfo)中添加一条交易记录,
147       同时应更新银行卡信息表(cardInfo)中的现有余额(如增加或减少500元)
148 */
149 /*--------------交易信息表插入交易记录--------------------------*/
150 INSERT INTO transInfo(transType,cardID,transMoney)
151       VALUES('支取','1010 3576 1234 5678',900) 
152 /*-------------更新银行卡信息表中的现有余额-------------------*/
153 UPDATE cardInfo SET balance=balance-900 WHERE cardID='1010 3576 1234 5678'
154  
155 /*--------------交易信息表插入交易记录--------------------------*/
156 INSERT INTO transInfo(transType,cardID,transMoney)
157       VALUES('存入','1010 3576 1212 1134',5000)  
158 /*-------------更新银行卡信息表中的现有余额-------------------*/
159 UPDATE cardInfo SET balance=balance+5000 WHERE cardID='1010 3576 1212 1134'
160 GO
161  
162 /*--------检查测试数据是否正确---------*/
163 SELECT * FROM cardInfo
164 SELECT * FROM transInfo
165  
166 /*$$$$$$$$$$$$$常规业务操作$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
167 /*---------修改密码-----*/
168 --1.张三(卡号为1010 3576 1234 5678)修改银行卡密码为123456
169 --2.李四(卡号为1010 3576 1212 1134)修改银行卡密码为123123
170 update cardInfo set pass='123456' WHERE cardID='1010 3576 1234 5678'
171 update cardInfo set pass='123123' WHERE cardID='1010 3576 1212 1134'
172 SELECT * FROM cardInfo
173 /*---------挂失帐号---------*/
174 --李四(卡号为1010 3576 1212 1134)因银行卡丢失,申请挂失
175 update cardInfo set IsReportLoss=1 WHERE cardID='1010 3576 1212 1134'
176 SELECT * FROM cardInfo
177 GO
178 /*--------查询余额3000~6000之间的定期卡号,显示该卡相关信息-----------------*/
179 SELECT * FROM cardInfo WHERE ((balance between 3000 and 6000) and (savingType='定期') )
180 /*--------统计银行的资金流通余额和盈利结算------------------------------*/
181 --统计说明:存款代表资金流入,取款代表资金.假定存款利率为千分之3,贷款利率为千分之8
182 DECLARE @inMoney money
183 DECLARE @outMoney money
184 DECLARE @profit money
185 SELECT * FROM transInfo
186 SELECT @inMoney=sum(transMoney) FROM transInfo WHERE (transType='存入')
187 SELECT @outMoney=sum(transMoney) FROM transInfo WHERE (transType='支取')
188 print '银行流通余额总计为:'+ convert(varchar(20),@inMoney-@outMoney)+'RMB'
189 set @profit=@outMoney*0.008-@inMoney*0.003
190 print '盈利结算为:'+ convert(varchar(20),@profit)+'RMB'
191 GO
192 /*--------查询本周开户的卡号,显示该卡相关信息-----------------*/
193 SELECT * FROM cardInfo WHERE (DATEDIFF(Day,getDate(),openDate)<DATEPART(weekday,openDate))
194 /*---------查询本月交易金额最高的卡号----------------------*/
195 SELECT * FROM transInfo
196 SELECT DISTINCT cardID FROM transInfo WHERE  transMoney=(SELECT Max(transMoney) FROM transInfo)
197 /*---------查询挂失帐号的客户信息---------------------*/
198 SELECT customerName as 客户姓名,telephone as 联系电话 FROM userInfo
199     WHERE customerID IN (SELECT customerID FROM cardInfo WHERE IsReportLoss=1)
200 /*------催款提醒:例如某种业务的需要,每个月末,如果发现用户帐上余额少于200元,将致电催款。---*/
201 SELECT customerName as 客户姓名,telephone as 联系电话,balance as 帐上余额
202       FROM userInfo INNER JOIN cardInfo ON  userInfo.customerID=cardInfo.customerID WHERE balance<200
203 /*$$$$$$$$$$$$$索引和视图$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
204 --1.创建索引:给交易表的卡号cardID字段创建重复索引
205 create NONCLUSTERED INDEX index_cardID ON transInfo(cardID)WITH FILLFACTOR=70
206 --2.按指定索引查询 张三(卡号为1010 3576 1212 1134)的交易记录
207 GO
208 SELECT * FROM transInfo (INDEX=index_cardID) WHERE cardID='1010 3576 1234 5678'
209 GO
210 --3.创建视图:为了向客户显示信息友好,查询各表要求字段全为中文字段名。
211 create VIEW view_userInfo  --银行卡信息表视图
212   AS
213     select customerID as 客户编号,customerName as 开户名, PID as 身份证号,
214         telephone as 电话号码,address as 居住地址  from userInfo
215 GO
216  
217 create VIEW view_cardInfo  --银行卡信息表视图
218   AS
219     select cardID as 卡号,curType as 货币种类, savingType as 存款类型,openDate as 开户日期,
220        balance as 余额,pass 密码,IsReportLoss as 是否挂失,customerID as 客户编号  from cardInfo
221 GO
222  
223 create VIEW view_transInfo  --交易信息表视图
224   AS
225     select transDate as 交易日期,transType as 交易类型, cardID as 卡号,transMoney as 交易金额,
226       remark as 备注  from transInfo
227 GO
228   
229  
230 /*$$$$$$$$$$$$$$$$$$$$$$存储过程$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
231 --1.取钱或存钱的存储过程
232   --drop proc proc_takeMoney
233 create procedure proc_takeMoney @card char(19),@m money,@type char(4),@inputPass char(6)=''
234  AS
235    print '交易正进行,请稍后......'
236    if (@type='支取')
237       if ((SELECT pass FROM cardInfo WHERE cardID=@card)<>@inputPass )
238          begin
239            raiserror ('密码错误!',16,1)
240            return
241          end
242  
243 DECLARE @myTransType char(4),@outMoney MONEY,@myCardID char(19)
244     SELECT @myTransType=transType,@outMoney=transMoney ,@myCardID=cardID FROM transInfo where cardID=@card
245     DECLARE @mybalance money
246     SELECT @mybalance=balance FROM cardInfo WHERE cardID=@card
247     if (@type='支取')
248        if (@mybalance>=@m+1)
249            update cardInfo set balance=balance-@m WHERE cardID=@myCardID
250        else
251           begin
252             raiserror ('交易失败!余额不足!',16,1)
253              
254             print '卡号'+@card+'  余额:'+convert(varchar(20),@mybalance)  
255             return
256           end
257     else
258          update cardInfo set balance=balance+@m WHERE cardID=@card
259  
260     print '交易成功!交易金额:'+convert(varchar(20),@m)
261     SELECT @mybalance=balance FROM cardInfo WHERE cardID=@card
262     print '卡号'+@card+'  余额:'+convert(varchar(20),@mybalance)
263 INSERT INTO transInfo(transType,cardID,transMoney) VALUES(@type,@card,@m)
264 GO
265 --2.调用存储过程取钱或存钱 张三取300,李四存500
266  --现实中的取款机依靠读卡器读出张三的卡号,这里根据张三的名字查出考号来模拟
267 declare @card char(19)
268 select @card=cardID from cardInfo Inner Join userInfo ON
269    cardInfo.customerID=userInfo.customerID where customerName='张三'
270 EXEC proc_takeMoney @card,300 ,'支取','123456'
271 GO
272  
273 declare @card char(19)
274 select @card=cardID from cardInfo Inner Join userInfo ON
275    cardInfo.customerID=userInfo.customerID where customerName='李四'
276 EXEC proc_takeMoney @card,500 ,'存入'
277 select * from view_cardInfo
278 select * from view_transInfo
279 GO
280 --3.产生随机卡号的存储过程(一般用当前月份数\当前秒数\当前毫秒数乘以一定的系数作为随机种子)
281   --drop proc proc_randCardID
282 create procedure proc_randCardID @randCardID char(19) OUTPUT
283   AS
284     DECLARE @r numeric(15,8)
285     DECLARE @tempStr  char(10)
286     SELECT  @r=RAND((DATEPART(mm, GETDATE()) * 100000 )+ (DATEPART(ss, GETDATE()) * 1000 )
287                   + DATEPART(ms, GETDATE()) )
288     set @tempStr=convert(char(10),@r) --产生0.xxxxxxxx的数字,我们需要小数点后的八位数字
289     set @randCardID='1010 3576 '+SUBSTRING(@tempStr,3,4)+' '+SUBSTRING(@tempStr,7,4)  --组合为规定格式的卡号
290 GO
291 --4.测试产生随机卡号
292 DECLARE @mycardID char(19)
293 EXECUTE proc_randCardID @mycardID OUTPUT
294 print '产生的随机卡号为:'+@mycardID
295 GO
296 --5.开户的存储过程
297    --drop proc proc_openAccount
298 create procedure proc_openAccount @customerName char(8),@PID char(18),@telephone char(13)
299      ,@openMoney money,@savingType char(8),@address varchar(50)=''
300   AS
301      DECLARE @mycardID char(19),@cur_customerID int
302      --调用产生随机卡号的存储过程获得随机卡号
303      EXECUTE proc_randCardID @mycardID OUTPUT
304      while  exists(SELECT * FROM cardInfo WHERE cardID=@mycardID)
305         EXECUTE proc_randCardID @mycardID OUTPUT
306      print '尊敬的客户,开户成功!系统为您产生的随机卡号为:'+@mycardID
307      print '开户日期'+convert(char(10),getdate(),111)+'  开户金额:'+convert(varchar(20),@openMoney)
308      IF not exists(select * from userInfo where PID=@PID)
309        INSERT INTO userInfo(customerName,PID,telephone,address )
310           VALUES(@customerName,@PID,@telephone,@address)
311      select @cur_customerID=customerID from userInfo where PID=@PID
312      INSERT INTO cardInfo(cardID,savingType,openMoney,balance,customerID)
313          VALUES(@mycardID,@savingType,@openMoney,@openMoney,@cur_customerID)
314       
315 GO
316  
317 --6.调用存储过程重新开户
318 EXEC proc_openAccount '王五','334456889012678','2222-63598978',1000,'活期','河南新乡'
319 EXEC proc_openAccount '赵二','213445678912342222','0760-44446666',1,'定期'
320 select * from view_userInfo
321 select * from view_cardInfo
322 GO
323  
324 /*$$$$$$$$$$$$$$$$$$$$$$事   务$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
325 --1.转帐的事务存储过程
326 --drop proc proc_transfer
327 create procedure proc_transfer @card1 char(19),@card2 char(19),@outmoney money
328  AS
329    begin tran
330      print '开始转帐,请稍后......'
331      DECLARE @errors int
332      set @errors=0
333  
334      EXEC proc_takeMoney @card1,@outmoney ,'支取','123123'
335      set @errors=@errors+@@error
336      EXEC proc_takeMoney @card2,@outmoney ,'存入'
337      set @errors=@errors+@@error
338      if (@errors>0)
339         begin
340           print '转帐失败!'
341           rollback tran
342         end
343      else
344         begin
345           print '转帐成功!'
346           commit tran
347         end
348 GO
349  
350 --2.测试上述事务存储过程
351 --从李四的帐户转帐2000到张三的帐户
352 --同上一样,现实中的取款机依靠读卡器读出张三/李四的卡号,这里根据张三/李四的名字查出考号来模拟
353 declare @card1 char(19),@card2 char(19)
354 select @card1=cardID from cardInfo Inner Join userInfo ON
355    cardInfo.customerID=userInfo.customerID where customerName='李四'
356 select @card2=cardID from cardInfo Inner Join userInfo ON
357    cardInfo.customerID=userInfo.customerID where customerName='张三'
358 --调用上述事务过程转帐
359 EXEC proc_transfer @card1,@card2,2000
360  
361 select * from view_userInfo
362 select * from view_cardInfo
363 select * from view_transInfo
364 GO
365 /*$$$$$$$$$$$$$$$$$$$$$$安    全$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
366 --1.添加SQL登录帐号
367 If not exists(SELECT * FROM master.dbo.syslogins WHERE loginname='sysAdmin')
368     begin
369       EXEC sp_addlogin 'sysAdmin', '1234'    --添加SQL登录帐号
370       EXEC   sp_defaultdb  'sysAdmin' , 'bankDB' --修改登录的默认数据库为bankDB
371     end
372   go
373 --2.创建数据库用户
374   EXEC sp_grantdbaccess  'sysAdmin', 'sysAdminDBUser'
375   GO
376 --3.--------给数据库用户授权
377   --为sysAdminDBUser分配对象权限(增删改查的权限)
378   GRANT SELECT,insert,update,delete,select  ON transInfo TO sysAdminDBUser   
379   GRANT SELECT,insert,update,delete,select  ON userInfo TO sysAdminDBUser  
380   GRANT SELECT,insert,update,delete,select  ON cardInfo TO sysAdminDBUser   
381 GO
382   
383  
384

  查询 : SELECT LastName,FirstName FROM Persons

select 1 from Persons;   Persons有100条记录,就会有100个1;

 查询用户所拥有的表:select table_name,owner from all_tables where owner='ORACLE_NAME' -- 注意大小写

增加 :INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees')

         SELECT LastName,FirstName INTO Persons_backup FROM Persons(从已有表中赋值到新字段)

         create table temp_lj as select * from persist_test1; (复制表结构以及数据)

         create table temp_lj2 as select * from persist_test1 where 1=2(只复制表结构);

         insert /* append */ into persist_test1@uat32 select * from persist_test1(只复制数据);

 

        --select * into target_table from source_table;//这是sql server的

        insert into target_table(column1,column2) select column1,5 from source_table;

        insert into temp_lj2 select * from z_student;

备份(字段一致): insert into  fast.coverage_1124
              select * from coverage ca
             where ca.policyno=i_contractno
        and ca.productid=i_old_productid;

更新 :UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson'

        

update t1
         set t1.c2 = t2.c2
       from t2

where t1.c1 = t2.c1

 

删除 :数据库操作语言(dml):DELETE FROM Person WHERE LastName = 'Wilson' (DELETE 语句用于删除表中的行,事务日志中为所删除的每行记录一个项,即可以触发触发器,可以回滚)

        数据库定义语言(ddl) truncate、drop,操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger:

         TRANCATE TABLE 表名称 (删除表(表的结构、属性以及索引不会被删除),事务日志中不会为所删除的每行记录一个项不可以触发触发器,不可以回滚,相对delete和drop当然速度更快)

         DROP TABLE 表名称 (删除表(表的结构、属性以及索引也会被删除),事务日志中不会为所删除的每行记录一个项,不可以触发触发器,不可以回滚)

 is null,is not null

like ,not like

 

建立数据库

if exists(select * from sysdatabases where name='MicroBlog')
    begin
      drop database microblog
    end
go

create database MicroBlog
on primary
(
 name = 'MicroBlog_data',
 filename = 'f:\databse\blog\MicroBlog_data.mdf',
 size = 3mb,
 filegrowth = 15%
)
log on
(
 name = 'MicroBlog_log',
 filename = 'f:\databse\Blog\MicroBlog_log.ldf',
 size = 1mb,
 filegrowth = 5%
)
go

 

建立表:(表中创建约束,在字段中)
create table BlogMessage
(
BlogID int identity(1,1) primary key,
BlogMessage varchar(280) not null,
BlogForwardCounts int,
BlogReviewedCounts int,
BlogForwardID int references UserInfo(UID),
BlogReviewedID int references UserInfo(UID),
BlogIssueTimes datetime default(getdate())
)
go

 

创建约束 :(表中创建,在字段后)

CREATE TABLE T_flow_procedure
(
Step_id int references T_flow_step_def(Step_id),
Flow_type_id char(3) references T_flow_type(Flow_type_id),
CONSTRAINT PK_T_flow_procedure_Step_id_AND_Flow_type_id PRIMARY KEY(Step_id, Flow_type_id),
)
go

               表外创建

ALTER TABLE cardInfo
  ADD CONSTRAINT  PK_cardID  PRIMARY KEY(cardID),
      CONSTRAINT  CK_cardID  CHECK(cardID LIKE '1010 3576 [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]'),
      CONSTRAINT  DF_curType  DEFAULT('RMB') FOR curType,
      CONSTRAINT  CK_savingType  CHECK(savingType IN ('活期','定活两便','定期')),
      CONSTRAINT  DF_openDate  DEFAULT(getdate()) FOR openDate,
      CONSTRAINT  CK_openMoney  CHECK(openMoney>=1),
      CONSTRAINT  CK_balance  CHECK(balance>=1),
      CONSTRAINT  CK_pass  CHECK(pass LIKE '[0-9][0-9][0-9][0-9][0-9][0-9]'),
      CONSTRAINT  DF_pass  DEFAULT('888888') FOR pass,
      CONSTRAINT  DF_IsReportLoss DEFAULT(0) FOR IsReportLoss,
      CONSTRAINT  FK_customerID FOREIGN KEY(customerID) REFERENCES userInfo(customerID)
GO

 

创建视图

create or replace view v_bookverify

as

select customerID as 客户编号,customerName as 开户名, PID as 身份证号,
        telephone as 电话号码,address as 居住地址  from userInfo

go

 

创建存储过程

CREATE PROCEDURE proc_book_price
@speciality_name varchar(20)
AS
BEGIN
declare @result float
    SELECT @result=sum (p.quantity*b.price)  from t_purchase p inner join t_book  b on p.book_id=b.id
       inner join t_speciality s on b.speciality_id=s.id
          where s.name=@speciality_name
return @result
END

 

调用存储过程

EXEC proc_book_price '赵二'

go

 

distinct

select * from hangkong_guiji_test ;

 

 

 

select distinct sfz from hangkong_guiji_test;

 

 

select distinct sfz,hbh from hangkong_guiji_test;

 

 

连接查询:内连接(inner join)、外连接(left join又名left outer join、right join又名right outer join、full join又名full outer join)、自然连接(natural join)、等值连接。

自然连接(Natural join)是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果中把重复的属性列去掉。而等值连接并不去掉重复的属性列。

如A中a,b,c字段,B中有c,d字段,则select * from A natural join B  相当于 select A.a,A.b,A.c,B.d from A.c = B.c  。
 
内连接和等值连接是一样的。

两个表:
A(id,name)
数据:(1,张三)(2,李四)(3,王五)
B(id,name)
数据:(1,学生)(2,老师)(4,校长)

内连接结果:
select A.*,B.* from A inner join B on A.id=B.id;
1 张三 1    学生
2 李四 2    老师

左外连接结果:左边的结果都查出来
select A.*,B.* from A left join B on A.id=B.id;
1 张三 1    学生
2 李四 2    老师
3 王五 NULL NULL

右外链接结果:右边的结果都查出来
select A.*,B.* from A right join B on A.id=B.id;
1    张三 1 学生
2    李四 2 老师
NULL NULL 4 校长

交叉连接(全外连接): 都查出来,左边的数据计数乘以右边的数据计数
select A.*,B.* from A full join B on A.id=B.id;
1 张三 1    学生
2 李四 2    老师
3 王五 NULL NULL
NULL NULL 4 校长

****************
补充:下面这种情况就会用到外连接
比如有两个表一个是用户表,一个是交易记录表,如果我要查询每个用户的交易记录就要用到左外外连接,因为不是每个用户都有交易记录。
用到左外连接后,有交易记录的信息就会显示,没有的就显示NULL,就像上面我举得例子一样。
如果不用外连接的话,比如【王五】没有交易记录的话,那么用户表里的【王五】的信息就不会显示,就失去了查询所有用户交易记录的意义了。即使没有交易记录,也要表明此用户是空的,不能名字都不列出来,就像查询所有的成绩,即使是0分也要把他的名字列出来

 

HAVING (特殊的'where',where是在查询时用,而它是查询完之后再用的)
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
HAVING SUM(OrderPrice)<2000

GROUP BY(将结果以组的形式显示)
下面是例子表
O_Id     OrderDate     OrderPrice     Customer
1     2008/12/29       1000               Bush
2     2008/11/23       1600               Carter
3     2008/10/05       700               Bush
4     2008/09/28       300               Bush
5     2008/08/06       2000               Adams
6     2008/07/21       100               Carter


---用group by
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer

Customer     SUM(OrderPrice)
Bush                  2000
Carter                  1700
Adams                  2000

---不用group by
SELECT Customer,SUM(OrderPrice) FROM Orders

Customer     SUM(OrderPrice)
Bush                5700
Carter                5700
Bush                5700
Bush                5700
Adams                5700

 group by 后面的字段只能是from 后面的表里面的字段,不能是别名,不能是子查询查出的字段

使用 UNION 命令

Employees_China:

E_IDE_Name
01 Zhang, Hua
02 Wang, Wei
03 Carter, Thomas
04 Yang, Ming

Employees_USA:

E_IDE_Name
01 Adams, John
02 Bush, George
03 Carter, Thomas
04 Gates, Bi

实例

列出所有在中国和美国的不同的雇员名:

SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA

结果

E_Name
Zhang, Hua
Wang, Wei
Carter, Thomas
Yang, Ming
Adams, John
Bush, George
Gates, Bill

注释:这个命令无法列出在中国和美国的所有雇员。在上面的例子中,我们有两个名字相同的雇员,他们当中只有一个人被列出来了。UNION 命令只会选取不同的值。

使用 UNION ALL命令

 

使用 UNION ALL 命令

UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。

实例:

列出在中国和美国的所有的雇员:

SELECT E_Name FROM Employees_China
UNION ALL
SELECT E_Name FROM Employees_USA

结果

E_Name
Zhang, Hua
Wang, Wei
Carter, Thomas
Yang, Ming
Adams, John
Bush, George
Carter, Thomas
Gates, Bill

 

 

COUNT() 函数返回匹配指定条件的行数。SELECT COUNT(column_name) FROM table_name 

COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入)

1.SELECT COUNT(Customer) AS CustomerNilsen FROM Orders                           返回CustomerNilsen表中customer字段有值的行数的统计数
2.SELECT COUNT(Customer) AS CustomerNilsen FROM Orders WHERE Customer='Carter' 返回CustomerNilsen表中customer字段有值的行数的统计数,并且值是'Carter'
3.SELECT age,name,COUNT(1) AS CustomerNilsen FROM Orders 
WHERE name='张三' group by age,name 返回CustomerNilsen表中customer字段有值的行数的统计数,并且值是'张三',但是为什么要加,group by column_name
原因如下:
Student有列:ID,Name,Age
            1,张三,18
            2,李四,19
            3,王五,20
            4,赵六,21
按照第三条sql:查出结果是
age name count(1)
20 王五 1
21 赵六 1
18 张三 1
19 李四 1
Student有列:ID,Name,Age
            1,张三,18
            2,张三,19
            3,王五,20
            4,赵六,21
表的数据变成上面,你想如果不group by,ID为1和2的name相同,ID为1的age是显示18了,还是19了,ID为2的age是显示19了,还是18了,其实第一次表的数据不group by age没事,因为name都相同,但是
第二次表的数据的,name有相同的,错误上面指出了,为避免这张情况,所以用了聚集函数的sql语句规定都得group by 查询的字段

SUM() 函数返回数值列的总数(总额)。SELECT SUM(column_name) FROM table_name

SELECT Customer,SUM(OrderPrice)

FROM Orders

WHERE Customer='Bush' OR Customer='Adams'

GROUP BY Customer

HAVING SUM(OrderPrice)>1500

 

 

 

oracle字段自动增长

第一种

--表
create table STUDENT
(
ID NUMBER not null,
NAME VARCHAR2(20) default '男',
SEX VARCHAR2(4),
ADDRESS VARCHAR2(40),
MEMO VARCHAR2(60)
);
--序列
create sequence STU
minvalue 1
maxvalue 999999999999
start with 21
increment by 1
cache 20;
--触发器
create or replace trigger stu_tr
before insert on student
for each row
begin
select stu.nextval into :new.id from dual;
end stu_tr;

insert into STUDENT(name,sex) values('kingcat','m');
select * from STUDENT;


第二种
--表
create table aaaa
(
ID NUMBER not null,
NAME VARCHAR2(20) default '男',
SEX VARCHAR2(4),
ADDRESS VARCHAR2(40),
MEMO VARCHAR2(60)
);

--序列
create sequence STU
minvalue 1
maxvalue 999999999999
start with 21
increment by 1
cache 20;

insert into aaaa(ID,name,sex) values(STU.NEXTVAL,'kingcat','m');
select *from aaaa;

 
drop sequence STU;
drop trigger stu_tr;
drop table STUDENT;

 

连接字符串:SQL SERVER 和 ACCESS ,以及 MYSQL,是 用 "+", ORACLE 是 "||"

 

--创建用户
create user sungoal identified by sungoal;
--创建临时表空间
create temporary tablespace sungoal_temp
tempfile 'D:\oracle_table_space\sungoal_temp.dbf'
size 50m
autoextend on
next 50m maxsize 1024m;

--创建数据表空间
create tablespace sungoal_data
datafile 'd:\oracle_table_space\sungoal_data'
size 50m
autoextend on
next 50m maxsize 1024m;
--给用户指定表空间
alter user sungoal default tablespace sungoal_data temporary tablespace sungoal_temp;
--给用户赋权
grant connect,resource to sungoal;
--连接用户(需要到命令行窗口测试能不能连上,不能通过sql窗口)
--conn sungoal/sungoal


--drop user sungoal cascade;

 

赋予权限:grant select, insert, update, delete on fast.COVERAGE_1124 to WEIMENG;

解锁用户:alter user 用户名 account unlock


索引:索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构(类比书籍中的索引)

为什么要创建索引呢?这是因为,创建索引可以大大提高系统的性能。
  • 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。
  • 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
  • 第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。


     也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点, 但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。

  • 第一,创建索引和维护索引要耗费时间,这种时间随着数据 量的增加而增加。
  • 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  •  第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。


     索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列 上创建索引,例如:

  • 在经常需要搜索的列上,可以加快搜索的速度;
  • 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
  • 在经常用在连接的列上,这 些列主要是一些外键,可以加快连接的速度;
  • 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
  • 在经常需要排序的列上创 建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  • 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。



     同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点:

      • 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因 为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
      • 第二,对于那 些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比 例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
      • 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
      • 第四,当修改性能远远大于检索性能时,不应该创建索 引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因 此,当修改性能远远大于检索性能时,不应该创建索引。

 

posted on 2012-03-28 15:07  lovebeauty  阅读(1284)  评论(0编辑  收藏  举报

导航