sql 外键级联,触发器防删

1:外键好处很多啊,删除主表id  级联的子表id,不用sql命令,自动删除了.

用例:

用户表 user

id    name    age
4    张二蛋           25
5    田雨            25
6    罗三靶子          25

成绩表userscore

id    userid    score
4    4    100       

所谓外键是成绩表 设置的 此表的用户id是 user表的id

 2:

 

 另外去个好的名字,外键表-外键表关联的id-主表-主表id 这样看着名字就知道哪个表跟哪个表内的列关联了

删除测试  没问题

 插入外键表数值.若主表无此外键那个id 则报错

2:Sqlserver 触发器 记录删除 与修改

日志表

CREATE TABLE [dbo].[LOGR](
    [USERID] [varchar](50) NULL,
    [STRSQL] [varchar](max) NULL,
    [DATE] [varchar](8) NULL,
    [TIME] [varchar](8) NULL,
    [TABLNM] [nvarchar](50) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

触发器

CREATE TRIGGER [dbo].[KNMT_LOG] ON [dbo].[PATIENT] 
FOR UPDATE, DELETE 
AS
 
DECLARE @CLIENT AS VARCHAR(50)
DECLARE @DATE AS VARCHAR(8)
DECLARE @TIME AS VARCHAR(8)
DECLARE @USERNAME AS VARCHAR(50)
DECLARE @STATMT  AS VARCHAR(max)
DECLARE @strSQL AS VARCHAR(100)
 
SET @CLIENT = HOST_NAME()
SET @DATE = CONVERT(VARCHAR(8),GETDATE(),112)
SET @TIME =REPLACE(CONVERT(VARCHAR(8),GETDATE(),108),':','')
SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(50))+')'
 
CREATE TABLE #STATEMENT (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(5000))
INSERT INTO #STATEMENT  EXEC(@strSQL)
 
SELECT @STATMT=C3 FROM #STATEMENT
 
INSERT INTO LOGR(USERID,STRSQL,DATE,TIME,TABLNM) VALUES(@CLIENT,@STATMT,@DATE,@TIME,'PATIENT')

3:SQL server 实现触发器备份表数据

在项目里 一个表被增加  需要同步插入的数据 写了一个触发器

需要一个备份表  一个触发器

创建备份表

SELECT * INTO PATIENT_backup FROM PATIENT
 

触发器

CREATE TRIGGER [dbo].[Insert_back] ON [dbo].[PATIENT] 
FOR INSERT 
AS
BEGIN
 
    SET NOCOUNT ON;
    INSERT INTO PATIENT_backup(
        PATIENTID ,
        BIRTHDATE,
        SEX,
        ETHNICGROUP,
        COMMENTS,
        RETRIEVEAETITLE,
        ISSUEROFPATIENTID,
        PATIENTNAME
    )
    SELECT
         i.PATIENTID ,
        i.BIRTHDATE,
        i.SEX,
        i.ETHNICGROUP,
        '',
        i.RETRIEVEAETITLE,
        i.ISSUEROFPATIENTID,
        i.PATIENTNAME
      
    FROM
    inserted i
    
END

4:    有时候我们数据库表中的数据会莫名其妙的被删除,不知道是业务问题还是被黑了,所以我们想要在数据库操作层面对此进行制止,同时记录操作的日志,我们可以利用触发器来实现这个需求,测试数据:

if not object_id(N'T') is null
    drop table T
Go
Create table T([ID] int,[姓名] nvarchar(22))
Insert T
select 1,N'张三' union all
select 2,N'李四' union all
select 3,N'王五'
GO

新建日志表:

CREATE   TABLE TBLOG
(
    ID INT NOT NULL IDENTITY(1, 1) ,
    EVTIME DATETIME NOT NULL  DEFAULT ( GETDATE() ) ,            --访问时间
    [SQL] VARCHAR(300) ,                                         --执行的SQL语句
    USERID VARCHAR(128) NOT NULL DEFAULT ( SUSER_SNAME() ) ,     --连接的时候使用的哪个SQL登陆用户   
    HOSTNAME VARCHAR(128) NOT NULL DEFAULT ( HOST_NAME() ) ,     --客户端的机器名              
    LOGINID VARCHAR(128),                                        --客户端的登陆用户(OS的用户)
    APPNAME VARCHAR(128)NOT NULL DEFAULT ( APP_NAME())          --是从查询分析器,还是应用程序来执行的                          
) 
CREATE   TRIGGER TR_TBTEST ON T
    FOR DELETE
AS
    RAISERROR('错误',16,8)
    ROLLBACK TRAN
    
  --SQL  
    CREATE   TABLE #T
        (
          EVENTTYPE VARCHAR(20) ,
          PARAMETERS INT ,
          EVENTINFO VARCHAR(300)
        )  
   
    DECLARE @SPID VARCHAR(20)
    SET @SPID = CAST(@@SPID AS VARCHAR)
    INSERT  #T
            EXEC ( 'DBCC INPUTBUFFER (' + @SPID + ')'
                )
      
--进程信息
    DECLARE @USERID VARCHAR(128) ,                 --连接的时候使用的哪个SQL登陆用户        
        @HOSTNAME VARCHAR(128) ,                       --客户端的机器名                          
        @LOGINID VARCHAR(128) ,                 --客户端的登陆用户(OS的用户)  
        @APPNAME VARCHAR(128)            --是从查询分析器,还是应用程序来执行的                
 
    SELECT  @USERID = LOGINAME ,                        --连接的时候使用的哪个SQL登陆用户        
            @HOSTNAME = HOSTNAME ,                       --客户端的机器名                          
            @LOGINID = NT_USERNAME ,                            --客户端的登陆用户(OS的用户)  
            @APPNAME = PROGRAM_NAME      --是从查询分析器,还是应用程序来执行的                
    FROM    MASTER..SYSPROCESSES
    WHERE   SPID = @@SPID
 
    INSERT  TBLOG
            ( SQL ,
              USERID ,
              HOSTNAME ,
              LOGINID ,
              APPNAME
            )
            SELECT  EVENTINFO ,
                    @USERID ,
                    @HOSTNAME ,
                    @LOGINID ,
                    @APPNAME
            FROM    #T      
  GO 

DELETE FROM T WHERE id=1

查询日志和数据情况:

SELECT * FROM TBLOG
 
SELECT * FROM T

 5:一些触发器帮助

    # 启用、禁用触发器

--禁用触发器
disable trigger tgr_message on student;
--启用触发器
enable trigger tgr_message on student;

    # 查询创建的触发器信息

--查询已存在的触发器
select * from sys.triggers;
select * from sys.objects where type = 'TR';

--查看触发器触发事件
select te.* from sys.trigger_events te join sys.triggers t
on t.object_id = te.object_id
where t.parent_class = 0 and t.name = 'tgr_valid_data';

--查看创建触发器语句
exec sp_helptext 'tgr_message';

 6:删除规则

INSERT 和 UPDATE 规范类别
展开以显示有关该关系的“删除规则”和“更新规则”的信息。

删除规则
指定当数据库的最终用户尝试删除某一行,而该行包含外键关系所涉及的数据时所发生的情况。如果设置为:

无操作    显示一条错误信息,告知用户不允许执行该删除操作,DELETE 将被回滚。

级联      删除包含外键关系中所涉及的数据的所有行。

设置空    如果表的所有外键列都可接受空值,则将该值设置为空。仅适用于 SQL Server 2005

设置默认值    如果表的所有外键列均已定义默认值,则将该值设置为列定义的默认值。仅适用于 SQL Server 2005。

更新规则
指定当数据库的用户尝试更新某一行,而该行包含外键关系所涉及的数据时所发生的情况。如果设置为:

无操作    显示一条错误信息,告知用户不允许执行该删除操作,DELETE 将被回滚。

级联    删除包含外键关系中所涉及的数据的所有行。

设置空    如果表的所有外键列都可接受空值,则将该值设置为空。仅适用于 SQL Server 2005。

设置默认值    如果表的所有外键列均已定义默认值,则将该值设置为列定义的默认值。仅适用于 SQL Server 2005
原文地址:https://www.cnblogs.com/zuochanzi/p/14207019.html