当前位置:首页 > 技术 > 正文内容

SQL Server函数、游标、存储过程与触发器详解

访客 技术 2026年6月12日 1

一、函数类型解析

SQL Server 2008支持三种自定义函数:标量函数、内联表值函数与多语句表值函数。它们的共性与差异如下:

  • 共性:均采用CREATE FUNCTION定义语法,包含RETURNS子句及AS关键字
  • 差异
    • 标量函数返回单一数据值,表值函数返回表结构
    • 标量与多语句函数需包含BEGIN...END结构,而内联函数无需
    • 调用时标量函数需使用dbo.前缀

1. 标量函数示例


USE SQL_SYSTEM
GO
CREATE FUNCTION F_GET_ID(@NAME NVARCHAR(5))
RETURNS INT
AS
BEGIN
  DECLARE @ID INT
  SELECT @ID = 工号 FROM T_员工信息 WHERE 姓名 = @NAME
  RETURN @ID
END
GO

SELECT 姓名, dbo.F_GET_ID('李异峰') AS 工号 FROM T_员工信息 WHERE 姓名='李异峰'

2. 内联表值函数


CREATE FUNCTION F_GET_ATTENDANCE(@DATE DATE)
RETURNS TABLE
AS
RETURN (
  SELECT * FROM T_考勤 WHERE 日期 = @DATE
)
GO

SELECT * FROM F_GET_ATTENDANCE('2014-02-28')

3. 多语句表值函数


CREATE FUNCTION F_GET_FULL_RECORD(@DATE DATE)
RETURNS @RESULT TABLE 
(
  姓名 NVARCHAR(5), 工号 INT, 职位 NVARCHAR(10), 部门 NVARCHAR(5),
  是否夜班 NCHAR(1), 日期 DATE, 上班时间 FLOAT
)
AS
BEGIN
  INSERT INTO @RESULT
  SELECT Y.姓名, Y.工号, Y.职位, Y.部门, K.夜班, K.日期, K.上班时间
  FROM T_员工信息 Y
  JOIN T_考勤 K ON Y.工号 = K.工号
  WHERE K.日期 = @DATE
  RETURN
END
GO

SELECT * FROM F_GET_FULL_RECORD('2014-02-28')

二、游标操作

适用于逐行处理复杂数据集,类似C语言指针机制。

1. 数据读取示例


DECLARE CUR_EMPLOYEE SCROLL CURSOR FOR
SELECT 姓名, 工号, 职位, 部门 FROM T_员工信息 ORDER BY 工号

OPEN GLOBAL CUR_EMPLOYEE

DECLARE @NAME NVARCHAR(3), @ID INT, @POS NVARCHAR(10), @DEPT NVARCHAR(8)
PRINT '总记录数:' + CAST(@@CURSOR_ROWS AS NVARCHAR)

FETCH FIRST FROM CUR_EMPLOYEE INTO @NAME, @ID, @POS, @DEPT
WHILE @@FETCH_STATUS = 0
BEGIN
  PRINT CONCAT('姓名:', @NAME, ' 工号:', @ID, ' 职位:', @POS, ' 部门:', @DEPT)
  FETCH NEXT FROM CUR_EMPLOYEE INTO @NAME, @ID, @POS, @DEPT
END

CLOSE CUR_EMPLOYEE
DEALLOCATE CUR_EMPLOYEE

2. 数据更新示例


DECLARE CUR_UPDATE CURSOR FOR
SELECT 姓名, 工号, 职位, 部门 FROM T_yuangongxinxi FOR UPDATE

OPEN GLOBAL CUR_UPDATE

DECLARE @OLD_POS NVARCHAR(10), @NAME NVARCHAR(3)
PRINT '当前记录数:' + CAST(@@CURSOR_ROWS AS NVARCHAR)

FETCH NEXT FROM CUR_UPDATE INTO @NAME, @ID, @OLD_POS, @DEPT
WHILE @@FETCH_STATUS = 0
BEGIN
  UPDATE T_yuangongxinxi SET 工号 = 工号 + 100 WHERE CURRENT OF CUR_UPDATE
  FETCH NEXT FROM CUR_UPDATE INTO @NAME, @ID, @OLD_POS, @DEPT
END

CLOSE CUR_UPDATE
DEALLOCATE CUR_UPDATE

三、存储过程设计

使用Transact-SQL编写的可重复使用的程序模块。

1. 无参数查询


CREATE PROCEDURE SP_SELECT_EMPLOYEE
WITH RECOMPILE
AS
SELECT * FROM T_yuangongxinxi
GO

EXEC SP_SELECT_EMPLOYEE

2. 带参数更新


CREATE PROCEDURE SP_UPDATE_POSITION
@ID INT, @NEW_POS NVARCHAR(10), @MSG NVARCHAR(50) OUTPUT
AS
BEGIN
  DECLARE @OLD_POS NVARCHAR(10), @NAME NVARCHAR(3)
  SELECT @OLD_POS = 职位, @NAME = 姓名 FROM T_yuangongxinxi WHERE 工号 = @ID
  
  UPDATE T_yuangongxinxi SET 职位 = @NEW_POS WHERE 工号 = @ID
  SET @MSG = CONCAT('工号', @ID, '的', @NAME, '职位已从', @OLD_POS, '变更为', @NEW_POS)
END
GO

DECLARE @OUTPUT NVARCHAR(50)
EXEC SP_UPDATE_POSITION 101, '高级工程师', @OUTPUT OUTPUT
SELECT @OUTPUT AS 操作结果

四、触发器应用

用于实现数据完整性约束,分为DDL与DML两类。

1. DDL触发器


CREATE TRIGGER TR_PREVENT_DROP
ON DATABASE
FOR DROP_TABLE
AS
BEGIN
  ROLLBACK
  PRINT '禁止删除操作!'
END
GO

DROP TABLE AA

2. DML触发器


CREATE TRIGGER TR_LOG_UPDATE
ON AA INSTEAD OF UPDATE
AS
BEGIN
  INSERT INTO T_UPDATE_HOU SELECT * FROM inserted
  INSERT INTO T_UPDATE_QIAN SELECT * FROM deleted
  PRINT '更新操作已记录'
END
GO

UPDATE AA SET 职位 = '高级工程师' WHERE 工号 = 101
SELECT * FROM T_UPDATE_HOU
SELECT * FROM T_UPDATE_QIAN

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。