zoukankan      html  css  js  c++  java
  • 存储过程

    1.好久没写博客了,刚好有人提到存储过程,想想自己也写过,但是用的时候还是要去查阅原来数据库

    索性几天整理个笔记。(既然是笔记就没什么其他的介绍了)

       A.常用系统存储过程有:

    exec sp_databases; --查看数据库
    exec sp_tables;        --查看表
    exec sp_columns student;--查看列
    exec sp_helpIndex student;--查看索引
    exec sp_helpConstraint student;--约束
    exec sp_stored_procedures;
    exec sp_helptext 'sp_stored_procedures';--查看存储过程创建、定义语句
    exec sp_renamedb myTempDB, myDB;--更改数据库名称
    exec sp_defaultdb 'master', 'myDB';--更改登录名的默认数据库
    exec sp_helpdb;--数据库帮助,查询数据库信息
    exec sp_helpdb master;
    --表重命名
    exec sp_rename 'stu', 'stud';
    select * from stud;
    --列重命名
    exec sp_rename 'stud.name', 'sName', 'column';
    exec sp_help 'stud';
    --重命名索引
    exec sp_rename N'student.idx_cid', N'idx_cidd', N'index';
    exec sp_help 'student';
    
    --查询所有存储过程
    select * from sys.objects where type = 'P';
    select * from sys.objects where type_desc like '%pro%' and name like 'sp%';
    select APP_NAME ( ) as w --当前会话的应用程序
    
    select @@IDENTITY --返回最后插入的标识值 
    select USER_NAME() --返回用户数据库用户名
    
    SELECT @@CONNECTIONS --返回自上次SQL启动以来连接或试图连接的次数。 
    SELECT GETDATE() --当前时间 
    SELECT @@CPU_BUSY/100 --返回自上次启动SQL 以来 CPU 的工作时间,单位为毫秒
    
    USE tempdb SELECT @@DBTS as w --为当前数据库返回当前 timestamp 数据类型的值。这一 timestamp 值保证在数据库中是唯一的。 
    select @@IDENTITY as w --返回最后插入的标识值 
    SELECT @@IDLE as w --返回SQL自上次启动后闲置的时间,单位为毫秒 
    SELECT @@IO_BUSY AS w --返回SQL自上次启动后用于执行输入和输出操作的时间,单位为毫秒 
    SELECT @@LANGID AS w --返回当前所使用语言的本地语言标识符(ID)。 
    SELECT @@LANGUAGE AS w --返回当前使用的语言名 
    SELECT @@LOCK_TIMEOUT as w --当前会话的当前锁超时设置,单位为毫秒。 
    SELECT @@MAX_CONNECTIONS as w --返回SQL上允许的同时用户连接的最大数。返回的数不必为当前配置的数值 
    EXEC sp_configure --显示当前服务器的全局配置设置 
    SELECT @@MAX_PRECISION as w --返回 decimal 和 numeric 数据类型所用的精度级别,即该服务器中当前设置的精度。默认最大精度38。 
    select @@OPTIONS as w --返回当前 SET 选项的信息。 
    SELECT @@PACK_RECEIVED as w --返回SQL自启动后从网络上读取的输入数据包数目。 
    SELECT @@PACK_SENT as w --返回SQ自上次启动后写到网络上的输出数据包数目。 
    SELECT @@PACKET_ERRORS as w --返回自SQL启动后,在SQL连接上发生的网络数据包错误数。 
    SELECT @@SERVERNAME as w --返回运行SQL服务器名称。 
    SELECT @@SERVICENAME as w --返回SQL正在其下运行的注册表键名 
    SELECT @@TIMETICKS as w --返回SQL服务器一刻度的微秒数 
    SELECT @@TOTAL_ERRORS AS w --返回 SQL服务器自启动后,所遇到的磁盘读/写错误数。 
    SELECT @@TOTAL_READ as w --返回 SQL服务器自启动后读取磁盘的次数。 
    SELECT @@TOTAL_WRITE as w --返回SQL服务器自启动后写入磁盘的次数。 
    SELECT @@TRANCOUNT as w --返回当前连接的活动事务数。 
    SELECT @@VERSION as w --返回SQL服务器安装的日期、版本和处理器类型。

    B.用户自定义存储过程

      

     1、 创建语法
    
    create proc | procedure pro_name
        [{@参数数据类型} [=默认值] [output],
         {@参数数据类型} [=默认值] [output],
         ....
        ]
    as
        SQL_statements
     
    
       2、 创建不带参数存储过程
    
    --创建存储过程
    if (exists (select * from sys.objects where name = 'proc_get_student'))
        drop proc proc_get_student
    go
    create proc proc_get_student
    as
        select * from student;
    
    --调用、执行存储过程
    exec proc_get_student;
       3、 修改存储过程
    
    --修改存储过程
    alter proc proc_get_student
    as
    select * from student;
       4、 带参存储过程
    
    --带参存储过程
    if (object_id('proc_find_stu', 'P') is not null)
        drop proc proc_find_stu
    go
    create proc proc_find_stu(@startId int, @endId int)
    as
        select * from student where id between @startId and @endId
    go
    
    exec proc_find_stu 2, 4;
       5、 带通配符参数存储过程
    
    --带通配符参数存储过程
    if (object_id('proc_findStudentByName', 'P') is not null)
        drop proc proc_findStudentByName
    go
    create proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')
    as
        select * from student where name like @name and name like @nextName;
    go
    
    exec proc_findStudentByName;
    exec proc_findStudentByName '%o%', 't%';
       6、 带输出参数存储过程
    
    if (object_id('proc_getStudentRecord', 'P') is not null)
        drop proc proc_getStudentRecord
    go
    create proc proc_getStudentRecord(
        @id int, --默认输入参数
        @name varchar(20) out, --输出参数
        @age varchar(20) output--输入输出参数
    )
    as
        select @name = name, @age = age  from student where id = @id and sex = @age;
    go
    
    -- 
    declare @id int,
            @name varchar(20),
            @temp varchar(20);
    set @id = 7; 
    set @temp = 1;
    exec proc_getStudentRecord @id, @name out, @temp output;
    select @name, @temp;
    print @name + '#' + @temp;
     
       7、 不缓存存储过程
    
    --WITH RECOMPILE 不缓存
    if (object_id('proc_temp', 'P') is not null)
        drop proc proc_temp
    go
    create proc proc_temp
    with recompile
    as
        select * from student;
    go
    
    exec proc_temp;
       8、 加密存储过程
    
    --加密WITH ENCRYPTION 
    if (object_id('proc_temp_encryption', 'P') is not null)
        drop proc proc_temp_encryption
    go
    create proc proc_temp_encryption
    with encryption
    as
        select * from student;
    go
    
    exec proc_temp_encryption;
    exec sp_helptext 'proc_temp';
    exec sp_helptext 'proc_temp_encryption';
       9、 带游标参数存储过程
    
    if (object_id('proc_cursor', 'P') is not null)
        drop proc proc_cursor
    go
    create proc proc_cursor
        @cur cursor varying output
    as
        set @cur = cursor forward_only static for
        select id, name, age from student;
        open @cur;
    go
    --调用
    declare @exec_cur cursor;
    declare @id int,
            @name varchar(20),
            @age int;
    exec proc_cursor @cur = @exec_cur output;--调用存储过程
    fetch next from @exec_cur into @id, @name, @age;
    while (@@fetch_status = 0)
    begin
        fetch next from @exec_cur into @id, @name, @age;
        print 'id: ' + convert(varchar, @id) + ', name: ' + @name + ', age: ' + convert(char, @age);
    end
    close @exec_cur;
    deallocate @exec_cur;--删除游标
     
       10、 分页存储过程
    
    ---存储过程、row_number完成分页
    if (object_id('pro_page', 'P') is not null)
        drop proc proc_cursor
    go
    create proc pro_page
        @startIndex int,
        @endIndex int
    as
        select count(*) from product
    ;    
        select * from (
            select row_number() over(order by pid) as rowId, * from product 
        ) temp
        where temp.rowId between @startIndex and @endIndex
    go
    --drop proc pro_page
    exec pro_page 1, 4
    --
    --分页存储过程
    if (object_id('pro_page', 'P') is not null)
        drop proc pro_stu
    go
    create procedure pro_stu(
        @pageIndex int,
        @pageSize int
    )
    as
        declare @startRow int, @endRow int
        set @startRow = (@pageIndex - 1) * @pageSize +1
        set @endRow = @startRow + @pageSize -1
        select * from (
            select *, row_number() over (order by id asc) as number from student 
        ) t
        where t.number between @startRow and @endRow;
    
    exec pro_stu 2, 2;
     
    --Raiserror
    
    --Raiserror返回用户定义的错误信息,可以指定严重级别,设置系统变量记录所发生的错误。
    
       --语法如下:
    
    Raiserror({msg_id | msg_str | @local_variable}
      {, severity, state}
      [,argument[,…n]]
      [with option[,…n]]
    )
       -- msg_id:在sysmessages系统表中指定的用户定义错误信息
    
       -- msg_str:用户定义的信息,信息最大长度在2047个字符。
    
       -- severity:用户定义与该消息关联的严重级别。当使用msg_id引发使用sp_addmessage创建的用户定义消息时,raiserror上指定严重性将覆盖sp_addmessage中定义的严重性。
    
       -- 任何用户可以指定0-18直接的严重级别。只有sysadmin固定服务器角色常用或具有alter trace权限的用户才能指定19-25直接的严重级别。19-25之间的安全级别需要使用with log--选项。
    
       -- state:介于1至127直接的任何整数。State默认值是1。
    
    raiserror('is error', 16, 1);
    select * from sys.messages;
    --使用sysmessages中定义的消息
    raiserror(33003, 16, 1);
    raiserror(33006, 16, 1);
    -----------------------------------------------------------------------------------------------------------------------------------------------
    至此上面全部是抄的网上连篇博客,但是觉得第二篇很详细,哈哈!



    下面来看看我第一次写的:
    CREATE  PROCEDURE [dbo].[ProjectDoPerson] @ProjectID uniqueidentifier AS --ProjectID是代码调用时传过来的参数
    declare   @PersonID uniqueidentifier --定义PersonID变量
    declare   @ProjectPersonTaskID uniqueidentifier --同上
    declare   @ProjectTempEventID uniqueidentifier --同上
    declare   PersonCursor cursor for select a.PersonID from ProjectPersons a left join Persons b on a.PersonID=b.PersonID where a.ProjectID=@ProjectID and a.IsDeleted=0 and b.IsDeleted=0 and b.Status=0 --定义游标,可以理解为我要查找当前项目(ID)下的所有人员,得到一个集合
    open PersonCursor --打开这个游标
    fetch next from PersonCursor into @PersonID --遍历这个游标列表,这里可以理解为每循环一个值时,把当前这个值赋值给变量PersonID
    while (@@Fetch_status =0)--0 FETCH 语句成功 ;-1 FETCH 语句失败或此行不在结果集中;-2 被提取的行不存在。这个状态值是fetch next查询游标的返回状态
    begin 
    declare ProjectEventsCursor cursor for select ProjectTempEventID from View_ProjectEvents where ProjectID=@ProjectID --同上游标定义,当前项目下有哪些事件
    open ProjectEventsCursor --同上
    fetch next from ProjectEventsCursor into @ProjectTempEventID
    while (@@Fetch_status =0)
    begin
    set @ProjectPersonTaskID = NEWID()  --这里是用GUID作为主键ID
    if not exists(select * from ProjectPersonTasks where PersonId=@PersonID and ProjectID=@ProjectID and ProjectTempEventID=@ProjectTempEventID and IsDeleted=0) --检查,当前项目下的人员   和  当前项目  和   触发的事件  三个是否满足条件
    insert into ProjectPersonTasks(ProjectPersonTaskID,PersonId,ProjectID,ProjectTempEventID,IsDeleted) values(@ProjectPersonTaskID,@PersonID,@ProjectID,@ProjectTempEventID,0) --如果不存在就新加一条任务记录
    fetch next from ProjectEventsCursor into @ProjectTempEventID --循环下一条
    end
    close ProjectEventsCursor
    deallocate ProjectEventsCursor
    fetch next from PersonCursor into @PersonID    --循环下一条
    end
    close PersonCursor
    deallocate PersonCursor

     这个存储过程是一个工程项目中,一个项目下人员所触发事件的记录。

    USE [WAP_WORKSHEET]
    GO
    /****** Object:  StoredProcedure [dbo].[uspCreateWorkSheetSeq]    Script Date: 2020/6/19 14:30:02 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    
    
    ALTER Procedure  [dbo].[uspCreateWorkSheetSeq]
        @Result varchar(100)  OUTPUT,
        @Code VARCHAR(6)
    AS
    Begin Try
        BEGIN TRANSACTION
    
        DECLARE @TIME nvarchar(10),@INDEX INT
        SET @TIME = CONVERT(varchar(100), GETDATE(), 112)
    
        SELECT TOP 1 @INDEX=CURRENT_SN FROM WS_SEQ WITH (TABLOCKX) WHERE CODE=@Code AND DATE=@TIME
        IF @INDEX IS NULL
            BEGIN
                SET @INDEX=0
                INSERT INTO WS_SEQ VALUES (@Code,@TIME,@INDEX)
            END
        ELSE
            BEGIN
                SET @INDEX=@INDEX+1
                UPDATE WS_SEQ SET CURRENT_SN=@INDEX WHERE CODE = @Code AND DATE=@TIME
            END
            
        SET @Result=@Code+@TIME+RIGHT('0000'+CONVERT(varchar(4),@INDEX),4)
        COMMIT TRANSACTION
    End Try
    Begin Catch
            -- Determine if an error occurred.
            IF @@trancount > 0
                ROLLBACK TRANSACTION
    
            -- Return the error information.
            DECLARE @ErrorMessage NVARCHAR(4000),  @ErrorSeverity Int;
            SELECT @ErrorMessage = ERROR_MESSAGE(),@ErrorSeverity = ERROR_SEVERITY();
            RAISERROR(@ErrorMessage, @ErrorSeverity, 1);
    End Catch

      

  • 相关阅读:
    2016年3月3日
    性能测试之我解
    Vim命令合集
    vi-vim常用命令
    架构的本质是
    网站三层架构学习之一 分层式结构
    Spring 4 + Quartz 2.2.1 Scheduler Integration Example
    “城市民族工作条例”详解--建议废止
    字符串匹配处理
    LogBack简易教程
  • 原文地址:https://www.cnblogs.com/myloveblogs/p/5962044.html
Copyright © 2011-2022 走看看