SQLserver中的触发器和存储过程

news2024/9/20 18:27:46

在 SQL Server 中,触发器是一种特殊的存储过程,它在指定的数据库表上发生特定的数据修改事件时自动执行。触发器可以用于执行各种任务,如数据验证、数据审计、自动更新相关表等。

触发器的类型

SQL Server 支持以下几种类型的触发器:

  1. INSERT 触发器:在向表中插入新行时触发。

  2. UPDATE 触发器:在修改表中的现有行时触发。

  3. DELETE 触发器:在从表中删除行时触发。

  4. INSTEAD OF 触发器:在执行 UPDATE、DELETE 或 INSERT 操作之前触发,允许你自定义操作而不是执行默认操作。

触发器的创建

创建触发器的基本语法如下:

CREATE TRIGGER trigger_name
ON table_name
AFTER|INSTEAD OF {INSERT | UPDATE | DELETE}
AS
BEGIN
    -- 触发器的 SQL 代码
END

示例

假设我们有一个名为 Employees 的表,我们想要在每次插入新员工记录时自动记录这一操作到 AuditLog 表中。

  1. 创建触发器

CREATE TRIGGER trg_AfterInsertEmployee
ON Employees
AFTER INSERT
AS
BEGIN
    INSERT INTO AuditLog (Action, EmployeeID, ChangedDate)
    SELECT 'Insert', EmployeeID, GETDATE()
    FROM inserted
END

在这个例子中,trg_AfterInsertEmployee 是触发器的名称,它在 Employees 表上定义。当有新记录插入 Employees 表时,触发器会将操作记录到 AuditLog 表中。

  1. 使用 INSTEAD OF 触发器

如果你想要自定义 INSERT 操作,可以使用 INSTEAD OF 触发器。例如,假设我们想要在插入新员工之前验证数据:

CREATE TRIGGER trg_InsteadOfInsertEmployee
ON Employees
INSTEAD OF INSERT
AS
BEGIN
    IF (SELECT COUNT(*) FROM inserted WHERE Age < 18) > 0
    BEGIN
        RAISERROR ('Cannot insert employee under 18 years old.', 16, 1)
        ROLLBACK TRANSACTION
        RETURN
    END
    ELSE
    BEGIN
        INSERT INTO Employees (EmployeeID, Name, Age)
        SELECT EmployeeID, Name, Age
        FROM inserted
    END
END

在这个例子中,如果尝试插入年龄小于 18 岁的员工,触发器将阻止插入并返回错误。

注意事项

  • 触发器可以影响数据库性能,特别是在高频率更新的表上。

  • 触发器中的错误可能导致数据不一致,因此在生产环境中使用触发器时需要谨慎。

  • 触发器可以嵌套,但嵌套触发器可能导致复杂的逻辑和性能问题,应尽量避免。

创建一个insert的触发器

CREATE TRIGGER TRIGGER_STUDENT_AFTERINSERT ON STUDENT 
    AFTER INSERT
    AS 
    DECLARE @STUID INT, @STUNAME NVARCHAR(50),@STUAGE INT
    SELECT @STUID=STUID, @STUNAME=STUNAME,@STUAGE=STUAGE FROM STUDENT
    PRINT CONVERT(VARCHAR,@STUID)+','+@STUNAME+','+ CONVERT(VARCHAR,@STUAGE)
    INSERT INTO STUDENT01(STUID,STUNAME,STUAGE) VALUES(@STUID,@STUNAME,@STUAGE)

SQLserver中存储过程

在 SQL Server 中,存储过程是一组为了完成特定功能的 SQL 语句集合,这些语句被保存在数据库中,可以通过一个调用语句来执行。存储过程可以接收参数、返回结果,并且可以进行复杂的逻辑处理。

存储过程的优点

  1. 性能优化:预编译的 SQL 语句可以提高执行效率。

  2. 安全性:通过存储过程,可以限制用户直接访问数据库表,只允许通过存储过程来操作数据,从而提高数据安全性。

  3. 重用性:可以重复使用存储过程,减少代码冗余。

  4. 减少网络流量:逻辑封装在服务器端,减少了客户端和服务器端之间的通信。

  5. 事务管理:可以在存储过程中方便地管理事务。

创建存储过程

创建存储过程的基本语法如下:

CREATE PROCEDURE ProcedureName
    @param1 DataType,
    @param2 DataType
AS
BEGIN
    -- SQL statements
END

示例

假设我们想要创建一个存储过程来插入新员工的信息:

CREATE PROCEDURE AddEmployee
    @EmployeeID INT,
    @EmployeeName NVARCHAR(100),
    @Department NVARCHAR(100)
AS
BEGIN
    INSERT INTO Employees (EmployeeID, Name, Department)
    VALUES (@EmployeeID, @EmployeeName, @Department)
END

调用存储过程

调用存储过程使用 EXECEXECUTE 语句:

EXEC AddEmployee @EmployeeID = 1, @EmployeeName = 'John Doe', @Department = 'Sales'

参数化存储过程

存储过程可以有输入参数、输出参数和返回值:

CREATE PROCEDURE GetEmployeeByID
    @EmployeeID INT,
    @EmployeeName NVARCHAR(100) OUTPUT
AS
BEGIN
    SELECT @EmployeeName = Name FROM Employees WHERE EmployeeID = @EmployeeID
END

调用带有输出参数的存储过程:

DECLARE @Name NVARCHAR(100)
EXEC GetEmployeeByID @EmployeeID = 1, @EmployeeName = @Name OUTPUT
SELECT @Name AS EmployeeName

错误处理

存储过程中可以使用 TRY...CATCH 语句进行错误处理:

CREATE PROCEDURE ProcessData
AS
BEGIN
    TRY
        -- 可能出错的 SQL 语句
   END
   CATCH
   BEGIN
       SELECT 
           ERROR_NUMBER() AS ErrorNumber,
           ERROR_MESSAGE() AS ErrorMessage
   END
END

存储过程的修改和删除

  • 修改存储过程:使用 ALTER PROCEDURE 语句。

  • 删除存储过程:使用 DROP PROCEDURE 语句。

ALTER PROCEDURE ProcedureName
AS
BEGIN
    -- 新的 SQL 语句
END
​
DROP PROCEDURE ProcedureName

注意事项

  • 存储过程可以非常复杂,包含循环、条件语句等。

  • 存储过程可以调用其他存储过程。

  • 存储过程的权限可以精细控制,例如,可以限制谁可以执行特定的存储过程。

  • 存储过程的执行可以通过动态 SQL 来实现更高级的功能。

使用存储过程按日期生产编号

CREATE PROC PROCCREATENO  AS 
BEGIN 
DECLARE @NO VARCHAR(20),@LASTSTOCKNO VARCHAR(20) ,@STRTIMESTR VARCHAR(8)
SET @STRTIMESTR= CONVERT(VARCHAR(8),GETDATE(),112)
SELECT @LASTSTOCKNO =(SELECT TOP 1 STOCKNO FROM STOCK WHERE SUBSTRING(STOCKNO,1,8)=@STRTIMESTR ORDER BY STOCKNO DESC)
PRINT @LASTSTOCKNO
IF @LASTSTOCKNO IS NULL
BEGIN 
SET @NO= @STRTIMESTR+'00001'
END
ELSE 
BEGIN
DECLARE @LEN INT ,@LASTNO INT,@TEMPNO VARCHAR(5),@N INT
SET @LASTNO =CONVERT(INT,SUBSTRING(@LASTSTOCKNO,9,5))+1
SET @LEN=LEN(@LASTNO)
SET @TEMPNO=CONVERT(VARCHAR,@LASTNO)
SET @N=0;
WHILE(@N<5-@LEN)
BEGIN
SET @TEMPNO='0'+@TEMPNO
SET @N+=1
END
SET @NO=@STRTIMESTR+@TEMPNO
END
INSERT INTO STOCK(STOCKNO) VALUES(@NO)
END

使用EXEC PROCCREATENO执行结果

结果为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2073225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何构建基于Java SpringBoot的保险业务管理与数据分析系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

UE管理内容 —— FBX导入选项参考

目录 Static Mesh Options Skeletal Mesh Options Transform Miscellaneous Material Options Fbx File Information 命名规范 StaticMesh SkeletalMesh AnimationSequence MorphTarget 导入器将自动检测要导入的文件类型&#xff0c;并相应地调整其接口&#xff1…

Java学习_21_多线程JUC

文章目录 前言多线程并发与并行多线程的实现方式Thread类Runnable接口Callable接口和Future接口 Thread类的相关方法线程对象线程优先级守护线程出让线程/礼让线程插入线程/插队线程 线程的相关问题生命周期安全问题Lock锁死锁等待唤醒机制&#xff08;生产者和消费者&#xff…

微信服务号网页授权域名配置数不够方案验证

文章目录 问题说明方案验证涉及工具结论 问题说明 微信服务号网页授权域名只能配置两个&#xff0c;而又没法直接配置主域名的形式&#xff0c;目前只能选取其中的一个业务域名来进行统一跳转解决。 方案验证 服务号现有配置数量限制如下&#xff1a; 申请测试号验证&#…

数据仓库系列 5:什么是事实表和维度表,它们有什么作用?

目录 1. 引言&#xff1a;事实表与维度表的魔力2. 事实表&#xff1a;业务活动的数字足迹2.1 什么是事实表?2.2 事实表的特征2.3 事实表的类型2.4 事实表示例2.5 事实表的作用2.6 事实表的设计原则2.7 事实表的查询示例 3. 维度表&#xff1a;为数据赋予意义3.1 什么是维度表?…

Mysql语句性能优化

SQL查询过程 查询缓存&#xff1a; 执行查询语句的时候&#xff0c;会先查询缓存&#xff08;MySQL 8.0 版本后移除&#xff0c;因为这个功能不太实用&#xff09;。分析器&#xff1a; 没有命中缓存的话&#xff0c;SQL 语句就会经过分析器&#xff0c;分析器说白了就是要先看…

logistic方程求解和模拟

logistic规律可以用以下式子表示 N(t1)​k*N(t)*​(N-N(t)) 其中N(t)为t时刻种群的数量&#xff0c;N为环境最大容纳的的种群数 k的取值通常与N有关&#xff0c;大约在1/N和4/N之间 题目如下 假设一些参数后的代码如下 T100; T11:T; N11000; a13/N1; Q800; N2700; a2-0.2/…

洛谷 P10119 『STA - R4』踱步

题目来源于&#xff1a;洛谷 题目本质&#xff1a;动态规划及优化&#xff0c;单调队列 题目思路&#xff1a; 设 fi,k,op​ 表示对于前 i 个位置&#xff0c;强制在 i1 分钟初踱步&#xff0c;总共踱步 k 次&#xff0c;且第 i 分钟在屋内&#xff08;op0&#xff09;或屋外…

leetcode73. 矩阵置零,简单模拟

leetcode73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示…

Stable Diffusion之提示词指南(二)

在上一篇的文章中&#xff0c;我们讲解了Stable Diffusion提示词的基本用法&#xff0c;不了解的到可以去学习一下———Stable Diffusion之提示词指南(一)。这章我们再详细讲解一下其他高级用法和负提示词。 注意&#xff1a;部分语法只是适用于AUTOMATIC1111 Web UI(以下简称…

SpringBoot集成kafka-指定topic(主题)-partition(分区)-offset(偏移量)消费信息

SpringBoot集成kafka-指定topic-partition-offset消费信息 1、消费者2、生产者3、配置类4、配置文件5、实体类6、工具类7、测试类8、第一次测试&#xff08;读取到19条信息&#xff09;9、第二次测试&#xff08;读取到3条信息&#xff09; 1、消费者 指定消费者读取配置文件中…

[pytorch] --- pytorch环境配置

本教程环境搭建基于windows 1 安装miniconda 1.1 miniconda与anaconda的区别 包含的包: Anaconda: 是一个较大的发行版&#xff0c;预装了大量的科学计算和数据分析相关的 Python 包。Miniconda: 更轻量级&#xff0c;只包含 Conda、Python 和它们的依赖&#xff0c;以及少…

微信小程序获取用户openId并通过服务端向用户发送模板消息

1.引言 注意&#xff1a; 1.标题中的服务端是自己研发的服务端&#xff0c;不是腾讯公司的服务端。 2.小程序的模板消息分为一次性订阅消息与长期订阅&#xff0c;一次性订阅就是每次在给用户发送消息之前都需要获得用户的同意&#xff08;即用户订阅&#xff09;&#xff0…

数据结构(树、平衡树、红黑树)

目录 树 树的遍历方式 平衡二叉树 旋转机制 左旋 右旋 旋转实例 左左 左右 右右 右左 总结 红黑树 树 相关概念 节点的内部结构如下 二叉树与二叉搜索树的定义 树的遍历方式 前序遍历&#xff1a;当前节点&#xff0c;左子节点&#xff0c;右子结点 中序遍历&a…

React学习day01-React-开发环境配置、JSX基础-本质、JSX中js表达式的用法、JSX的条件渲染

1、React &#xff08;1&#xff09;概念&#xff1a;由Meta公司研发&#xff0c;是一个用于构建Web和原生交互页面的库 &#xff08;2&#xff09;优点&#xff1a; 1&#xff09;相较于传统基于DOM开发的优势&#xff1a;组件化的开发方式、不错的性能 2&#xff09;相较于…

软件设计原则之单一职责原则

目录 单一职责原则单一职责原则的主要特点应用范围Demo用户信息日志记录 单一职责原则 单一职责原则&#xff08;Single Responsibility Principle&#xff0c;简称SRP&#xff09;是面向对象设计中的一个重要原则&#xff0c;其核心思想是&#xff1a;一个类应该仅有一个引起…

ollma 本地部署大模型

因为我本地是 windows 的系统&#xff0c;所以这里直接写的是通过 docker 来实现本地大模型的部署。 windows 下 WSl 的安装这里就不做重复&#xff0c;详见 windows 部署 mindspore GPU 开发环境&#xff08;WSL&#xff09; 一、Docker 部署 ollma 1. 拉取镜像&#xff08;…

Ubuntu系统设置Java项目开机自启

1、创建自启动脚 sudo vi /etc/systemd/system/java-service.service 2、编辑自启脚本 [Unit]部分包含了service的描述和依赖关系。在这个示例中&#xff0c;我们将其设置为在系统启动后执行。 [Service]部分定义了service的执行方式。在这个示例中&#xff0c;我们指定了Java…

shell工具箱集合!!

shell工具箱集合 1.shell工具箱集合 2.Chrony 时间同步 3.Get_host_Info 设备信息收集 4.Init_host 系统初始化 5.Iperf 带宽测试套件 6.Lagscope_test 时延测试套件 7.Mtr_test 双向路由探测套件 下载地址&#xff1a; https://pan.quark.cn/s/6936cc13bc04

学习笔记——Redis基础

文章目录 Redis五种常用数据类型Redis常用命令Spring Data Redis使用方式操作步骤 Redis五种常用数据类型 Redis存储的是key-values结构的数据&#xff0c;其中key是字符串类型&#xff0c;value有五种常用的数据类型&#xff1a; 字符串&#xff08;string&#xff09;&…