目录
6.索引
8.事务
一. 视图(视图名:View_Test 表名:Tab_Test)
--判断是否存在-- if exists (select * from sysobjects where name = 'View_Test') drop view View_Test go --创建视图 create view View_Test as select * from Tab_Test where id>1 go --使用视图-- select *from View_Test
-- 创建存储 CREATE PROCEDURE proc_Test( @flag VARCHAR(20)='' ) AS BEGIN -- 如果@flag=1则执行 IF(@flag='1') BEGIN SELECT 1; END ELSE IF(@flag='2') BEGIN SELECT 2; END ELSE BEGIN SELECT 3; END END -- 删除存储 drop PROCEDURE proc_Test;
-- 是否存在存储 if exists (select * from dbo.sysobjects where id =object_id(N'[dbo].[存储过程名]') and OBJECTPROPERTY(id,N'IsProcedure') = 1) --示例 if exists (select * from dbo.sysobjects where id =object_id(N'proc_Test') and OBJECTPROPERTY(id,N'IsProcedure') = 1) drop procedure proc_Test; go
CREATE function func_Test ( @Strs varchar(max), --需要被分隔的字符串 @Split varchar(50) --分隔符 ) returns @Temp table (id varchar(50) null) as begin while (charindex(@Split, @Strs)<>0) begin insert @Temp(id) values (substring(@Strs, 1, charindex(@Split, @Strs)-1)) set @Strs=stuff(@Strs, 1, charindex(@Split, @Strs), '') end insert @Temp(id) values (@Strs) return end
1.创建触发器的格式
go create trigger tr_触发器名字 on 表名 after|instead of update|delete|insert as begin 代码 end
2.案例
go create trigger test_Delete on department after delete as begin insert into department (id,name,createTime) select id,name,createTime from deleted end; -- 测试 delete from department ;
CREATE TRIGGER [dbo].[触发器名称] ON [dbo].[表名] WITH EXECUTE AS CALLER AFTER INSERT AS DECLARE @code VARCHAR(50) SET @code =''; UPDATE dbo.[表名] SET code = @code WHERE id IN ( SELECT id FROM inserted )
eg1:
CREATE PROCEDURE `proc_Test`(IN _startTime Date) BEGIN DECLARE done INT DEFAULT 0;-- 结束循环字段 declare acs int; declare acMDMID varchar(50); declare acName varchar(120); declare acCode varchar(200); declare acAccountPerson varchar(200); declare acCountry varchar(200); declare acAccountNum varchar(200); declare acMDMID_one varchar(200); DECLARE alist CURSOR FOR SELECT cMDMID FROM he_base_supplier b1 WHERE b1.bflag='0' AND (b1.cBkAccountNum='' OR b1.cBkAccountNum IS NULL); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN alist; /* 遍历数据表 */ read_loop:loop FETCH NEXT FROM alist INTO acMDMID; IF done =1 THEN LEAVE read_loop; END IF; SELECT cs,cMDMID,cName,cCode,cAccountPerson,cCountry,cAccountNum INTO acs,acMDMID_one,acName,acCode,acAccountPerson,acCountry,acAccountNum from ( SELECT COUNT(1) AS cs, t.cMDMID,-- 银行系统编码 t.cName,-- 开户行 t.cCode,-- 银行编码 t.cAccountPerson,-- 账户名称 t.cCountry,-- 银行国家 t.cAccountNum -- 银行账号 FROM he_base_supplierbank t inner join he_base_supplier b1 on b1.bflag='0' AND (b1.cBkAccountNum='' OR b1.cBkAccountNum IS NULL) and t.cGysMdmId=b1.cMDMID WHERE t.bflag='0' AND t.cGysMdmId=acMDMID GROUP BY t.cGysMdmId ) AS aa where aa.cs=1 ; if(acs=1) then update he_base_supplier t set t.cbkmdmid=acmdmid_one,t.cbkname=acname,t.cbkcode=accode,t.cbkaccountperson=acaccountperson,t.cbkcountry=accountry,t.cbkaccountnum=acaccountnum where t.cmdmid=acmdmid; commit; end if; SET done = 0; end loop read_loop; /* 关闭游标 */ CLOSE alist; END
eg2:
declare @userid varchar(40),@username varchar(40),@usercode varchar(40) DECLARE MyCursor CURSOR SCROLL DYNAMIC FOR select userid,username,usercode from userTable --为所获得的数据集指定游标 OPEN MyCursor --打开游标 fetch next from MyCursor into @userid,@username,@usercode --开始抓第一条数据 while(@@fetch_status=0) -- 如果数据集里一直有数据 begin --开始做想做的事(什么更新呀,删除呀) select * from userTable where userid=@userid; --UPDATE userTable SET username=@username WHERE CURRENT of MyCursor;--更新当前游标,如果是实表会被实际修改 --DELETE FROM userTable WHERE CURRENT OF MyCursor; --删除当前游标 --fetch absolute 2 from MyCursor into @userid,@username,@usercode --转到指定行,负数为倒数行,定义游标需指定 SCROLL --fetch relative 2 from MyCursor into @userid,@username,@usercode --转到与当前游标的相对行,负数为倒数,定义游标需指定 DYNAMIC --fetch first from MyCursor into @userid,@username,@usercode--转到与游标的首行 --fetch last from MyCursor into @userid,@username,@usercode--转到与游标的尾行 --fetch prior from MyCursor into @userid,@username,@usercode--转到与当前游标的前一行 fetch next from MyCursor into @userid,@username,@usercode --转到与当前游标的后一行(跳到下一条数据) end close MyCursor --关闭游标 deallocate MyCursor --删除游标
eg3:
-- 方法1:游标 -- 声明变量 DECLARE @empid AS INT, @firstname AS NVARCHAR(10), @lastname AS NVARCHAR(20); -- 声明游标 DECLARE C_Employees CURSOR FAST_FORWARD FOR SELECT empid,firstname,lastname FROM HR.Employees ORDER BY empid; OPEN C_Employees; -- 取第一条记录 FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname; WHILE @@FETCH_STATUS=0 BEGIN -- 操作 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid; -- 取下一条记录 FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname; END -- 关闭游标 CLOSE C_Employees; -- 释放游标 DEALLOCATE C_Employees;
六.索引
七.为查询列加上行号
SELECT * , ROW_NUMBER() OVER ( ORDER BY b_time ) AS 行号 FROM 表名
事务的开始:begin transaction
事务的提交:commit transaction
事务的回滚:rollback transaction
方式1:利用begin try--end try 、begin catch--end catch,来捕捉是否存在异常,从而来判断执行事务提交还是事务回滚。
begin transaction begin try SQL语句1 SQL语句2 commit transaction end try begin catch rollback transaction end catch
方式2:利用系统变量@@ERROR, 代表的意思为:记录最近一次SQL语句执行的状态码,如果大于0表示这条有错误,最终通过判断是否大于0,来决定是事务提交还是事务回滚。
begin transaction declare @myError int; --自定义变量 set @myError=0; SQL语句1 set @myError=@myError+@@ERROR; SQL语句2 set @myError=@myError+@@ERROR; if @myError>0 begin rollback transaction end else begin commit transaction end
九.多表关联更新
update a set a.name= b.name from Table1 a inner join Table2 b on a.ccode= b.code
十.sqlserver触发器(亲自测试过,借鉴:https://www.cnblogs.com/mcgrady/p/4182486.html)
触发器: 在对数据库数据进行操作(增加(insert)、修改(update)、删除(delete))后,可以自动执行的操作
触发器分为两类:instead of 触发器 ,after(for)触发器。
instead of 触发器:在数据更新到数据库之前执行的操作
after(for)触发器:在数据更新到数据后再执行的操作
数据临时载体:inserted和deleted
inserted:存储操作中新增的或者更新的数据
deleted:存储操作中删除的数据
-- 方法1:游标 -- 声明变量 DECLARE @empid AS INT, @firstname AS NVARCHAR(10), @lastname AS NVARCHAR(20); -- 声明游标 DECLARE C_Employees CURSOR FAST_FORWARD FOR SELECT empid,firstname,lastname FROM HR.Employees ORDER BY empid; OPEN C_Employees; -- 取第一条记录 FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname; WHILE @@FETCH_STATUS=0 BEGIN -- 操作 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid; -- 取下一条记录 FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname; END -- 关闭游标 CLOSE C_Employees; -- 释放游标 DEALLOCATE C_Employees;
十一.