温馨提示×

centos sqlserver触发器使用教程

小樊
35
2025-12-19 20:05:11
栏目: 云计算

CentOS 上使用 SQL Server 触发器的完整教程

一 环境准备与连接

  • CentOS 上安装并启动 Microsoft SQL Server,使用 sqlcmd 连接数据库:
    • 安装工具与服务器(示例为 RHEL/CentOS 7 系列,其他版本请替换对应 repo):
      • sudo yum install -y wget
      • wget https://packages.microsoft.com/config/rhel/7/prod.list
      • sudo tee /etc/yum.repos.d/mssql-release.repo
      • sudo yum install -y msodbcsql17 unixodbc-devel mssql-server
      • sudo systemctl start mssql-server
      • sudo systemctl enable mssql-server
    • 连接数据库(示例):
      • 本地信任连接:sudo sqlcmd -S localhost -E
      • 指定数据库:sudo sqlcmd -S localhost -d your_database -E
      • 账号密码:sudo sqlcmd -S localhost -U sa -P ‘YourStrong@Passw0rd’
  • 以上完成 SQL Server 在 Linux/CentOS 上的基本运行与连接准备。

二 触发器核心概念与语法

  • 触发器类型与事件
    • DML 触发器:响应表或视图上的 INSERT/UPDATE/DELETE;可用 AFTER(默认,FOR 同义)或 INSTEAD OF;视图仅支持 INSTEAD OF。同一表同一事件可定义多个 AFTER 触发器,可用 sp_settriggerorder 指定首个与末个;INSTEAD OF 每事件仅能有一个。触发器执行期间可使用两个逻辑表:inserted(新值)与 deleted(旧值)。
  • 基本语法
    • CREATE TRIGGER [schema.]trigger_name ON { table | view } { FOR | AFTER | INSTEAD OF } { [INSERT] [,][UPDATE] [,][DELETE] } [ WITH ] AS { sql_statement [;] […] | EXTERNAL NAME }
  • 常用要点
    • AFTER:触发语句及约束检查都成功后执行;INSTEAD OF:替代原语句执行。
    • 触发器内可访问 inserted/deleted 逻辑表进行条件判断与数据回写。
    • 可用 IF UPDATE(column) 判断某列是否被更新(仅 INSERT/UPDATE 有效)。

三 实战示例

  • 示例一 插入时自动写入时间戳
    • 目标:向表插入数据时,自动填充 created_at / updated_at
    • 建表与触发器:
      • CREATE TABLE dbo.products( id INT IDENTITY(1,1) PRIMARY KEY, name NVARCHAR(100), price DECIMAL(10,2), created_at DATETIME2, updated_at DATETIME2 );
      • GO
      • CREATE TRIGGER trg_products_Insert ON dbo.products AFTER INSERT AS BEGIN SET NOCOUNT ON; UPDATE p SET created_at = GETDATE(), updated_at = GETDATE() FROM dbo.products AS p JOIN inserted AS i ON i.id = p.id; END
      • GO
    • 验证:
      • INSERT INTO dbo.products(name, price) VALUES (N’笔记本’, 5999.00);
      • SELECT id, name, price, created_at, updated_at FROM dbo.products;
  • 示例二 更新审批状态并记录审计日志
    • 目标:当 status 变更时写入审计表,若变为 2(已审批) 则回滚禁止审批。
    • 建表与触发器:
      • CREATE TABLE dbo.orders( id INT IDENTITY(1,1) PRIMARY KEY, order_no NVARCHAR(50), status TINYINT, updated_at DATETIME2 );

      • CREATE TABLE dbo.orders_audit( id INT IDENTITY(1,1) PRIMARY KEY, order_id INT, old_status TINYINT, new_status TINYINT, change_time DATETIME2 );

      • GO

      • CREATE TRIGGER trg_orders_StatusChange ON dbo.orders AFTER UPDATE AS BEGIN SET NOCOUNT ON;

        – 记录审计 INSERT INTO dbo.orders_audit(order_id, old_status, new_status, change_time) SELECT d.id, d.status, i.status, GETDATE() FROM deleted AS d JOIN inserted AS i ON i.id = d.id WHERE d.status <> i.status;

        – 业务规则:已审批禁止再改回或变更 IF UPDATE(status) BEGIN IF EXISTS ( SELECT 1 FROM inserted AS i JOIN deleted AS d ON d.id = i.id WHERE d.status = 2 AND i.status <> 2 ) BEGIN RAISERROR(‘已审批订单不允许变更状态。’, 16, 1); ROLLBACK TRANSACTION; RETURN; END END END

      • GO

    • 验证:
      • INSERT INTO dbo.orders(order_no, status) VALUES (N’SO20251219001’, 1);
      • UPDATE dbo.orders SET status = 2 WHERE order_no = N’SO20251219001’; – 成功
      • UPDATE dbo.orders SET status = 1 WHERE order_no = N’SO20251219001’; – 触发回滚
  • 示例三 软删除标记
    • 目标:DELETE 时不真删,改为更新 is_deleted 与时间戳。
    • 建表与触发器:
      • CREATE TABLE dbo.customers( id INT IDENTITY(1,1) PRIMARY KEY, name NVARCHAR(100), is_deleted BIT NOT NULL DEFAULT 0, deleted_at DATETIME2 NULL );
      • GO
      • CREATE TRIGGER trg_customers_SoftDelete ON dbo.customers INSTEAD OF DELETE AS BEGIN SET NOCOUNT ON; UPDATE c SET is_deleted = 1, deleted_at = GETDATE() FROM dbo.customers AS c JOIN deleted AS d ON d.id = c.id; END
      • GO
    • 验证:
      • INSERT INTO dbo.customers(name) VALUES (N’张三’);
      • DELETE FROM dbo.customers WHERE name = N’张三’;
      • SELECT id, name, is_deleted, deleted_at FROM dbo.customers;
  • 说明
    • 上述示例均使用 AFTER/INSTEAD OFinserted/deleted、条件判断与 ROLLBACK 等常见模式,适合在 CentOS 上的 SQL Server 环境直接运行与验证。

四 管理与排错

  • 常用管理语句
    • 查看表上触发器:EXEC sp_helptrigger ‘schema.table’;
    • 查看触发器定义:EXEC sp_helptext ‘schema.trigger_name’;
    • 禁用/启用:DISABLE TRIGGER schema.trigger_name ON schema.table; / ENABLE TRIGGER schema.trigger_name ON schema.table;
    • 删除:DROP TRIGGER IF EXISTS schema.trigger_name;
    • 触发顺序:EXEC sp_settriggerorder @triggername = ‘schema.trigger_name’, @order = ‘First’ | ‘Last’, @stmttype = ‘INSERT’ | ‘UPDATE’ | ‘DELETE’;
  • 排错要点
    • 触发器是依附于 DML 的自动过程,不能显式调用;逻辑在 inserted/deleted 中,注意多行影响与集合化处理,避免只取单行变量导致逻辑错误。
    • 在触发器中如需阻止操作,使用 RAISERROR + ROLLBACK;注意事务与错误处理,避免“触发器中再触发”的无限递归(必要时控制触发顺序或改为 INSTEAD OF)。
    • 性能建议:保持触发器逻辑轻量;只处理必要列;避免在触发器中执行远程/跨库调用;对大批量导入可临时禁用非关键触发器并在导入后补跑审计。

0