zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    json for modern c++(nlohmann json)使用小计
    你到底是如何上网的[转载]
    opencv编译
    二维码解析(编译zxing-cpp)
    otl odbc小计
    解决github clone慢的问题
    网络编程小计
    模板小计
    c++开发遇到的错误和引用配置
    IOCP Input/Output Completion Port IO完成端口
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/14207019.html
Copyright © 2011-2022 走看看