Let's go

sqlserver 常用整理

目录

      1.视图

  2.存储

  3.函数

  4.触发器

  5.游标

  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;

 

 

十一.

posted @ 2019-12-26 16:55  chenze  阅读(372)  评论(0编辑  收藏  举报
有事您Q我