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
连接查询:
两个表:
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 后面的表里面的字段,不能是别名,不能是子查询查出的字段
Employees_China:
E_ID | E_Name |
---|---|
01 | Zhang, Hua |
02 | Wang, Wei |
03 | Carter, Thomas |
04 | Yang, Ming |
Employees_USA:
E_ID | E_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 命令几乎是等效的,不过 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
原因如下:
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 是 "||"
赋予权限:grant select, insert, update, delete on fast.COVERAGE_1124 to WEIMENG;
解锁用户:alter user 用户名 account unlock
索引:索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构(类比书籍中的索引)
也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点, 但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。
索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列 上创建索引,例如:
同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: