sql server—使用带条件计数的sql触发器审核数据库报表的最佳方法?

du7egjpx  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(381)

我希望在我的sql server中实现一个触发器,以便在进行报表编辑时保存它们。
服务器操作一个报告/口述软件包。基本上,“报告文本”草稿由user1创建,然后由user2编辑,最后由user2完成。user1的草稿被保存到一个表中,并且在数据库中的每次保存都会被覆盖,一旦user1完成并且user2进行编辑,数据就会被进一步覆盖。因此,一旦user2保存了他们的编辑,user1的最终草稿就丢失了。
一旦user1完成,我就试图将“report\u text”保存到一个新表中。
一个单独的表保存一个审核日志,其中包含报表id、访问时间和访问报表的用户。在最终确定之前,每次访问都会在审核表中插入新行,这样审核表中的每个报表id可以有2到4行(取决于在最终确定之前访问过文件的用户数)。当审核表中每个报表id的行数从2变为3时,触发器应捕获“报表文本”。

USE SERVER
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER trigger [dbo].[prelim_text_trigger]
on [dbo].[report_to_user]
AFTER INSERT
AS
BEGIN

SET NOCOUNT ON;

INSERT INTO
dbo.report_compare (report_id)

SELECT report_id
FROM inserted
WHERE (SELECT COUNT(report_id) 
FROM report_to_user 
GROUP BY report_id 
HAVING count(report_id) > 2);

END

我尝试了以下代码,但没有成功。没有插入任何内容 dbo.report_compare 审计表也有问题 dbo.report_to_user 当扳机启动的时候。我认为触发器失败,事务正在回滚。
我做错什么了?我是否应该做一个条件语句,以便在不满足条件的情况下继续交易?这是否准确地计算了整个表中报表id存在的示例数,还是仅从临时表中计算 from inserted ?
展望未来,如果触发器失败,我希望事务继续。如果我加上 XACT_ABORT OFF 或者 COMMIT TRANS 到了扳机的开头那会起作用吗?
还有,你应该 FOR EACH ROW 是否添加到此触发器,以防数据库同时保存多个报告?
更新
此后,我对守则作了如下修改:

ALTER trigger [dbo].[report_compare_trigger]
on [dbo].[report_test_to_user]
after insert

as
set xact_abort off
begin

set nocount on;

merge report_compare as target 
    using (select report_id from inserted) as source (report_id) 
    on (target.report_id = source.report_id)
    when not matched then insert (report_id) values (report_id);

if (select accession_id from report_compare where report_compare.report_id = (select report_id from inserted)) is null
    begin
        update report_compare
        set accession_id = id from accession_test
        where report_compare.report_id = (select report_id from inserted) and accession_test.report_id = (select report_id from inserted);
    end

update report_compare
    set report_compare.id_count = id_count + 1 
    where report_compare.report_id = (select report_id from inserted);

if (select date_opened from report_compare where report_compare.report_id = (select report_id from inserted)) is null
    begin
        update report_compare
        set date_opened = cre_time from report_test_section
        where report_compare.report_id = (select report_id from inserted) and report_test_section.report_id = (select report_id from inserted);
    end

if (select user_id from inserted) <> 'EmergencyDept'
    begin
        if (select users from report_compare where report_compare.report_id = (select report_id from inserted)) is null
            begin
                update report_compare
                set users = isnull(users, '') + user_id from inserted where report_compare.report_id = (select report_id from inserted)
            end
        else
            begin
update report_compare
        set users = isnull(users, '') + ', ' + user_id from inserted where report_compare.report_id = (select report_id from inserted)
            end
    end

end;
jexiocij

jexiocij1#

可能有点离题,但听起来您可能会从时态表中受益—可从sql server 2016获得。sql server还具有审计功能,因此您不必完全重新设计轮子。
我尝试了以下代码,但没有成功。没有将任何内容插入dbo.report\u compare,并且在触发器运行时,审核表dbo.report\u to\u user出现问题。
什么样的问题?
这个语句实际上返回一行吗?

SELECT report_id
FROM inserted
WHERE (SELECT COUNT(report_id) 
FROM report_to_user 
GROUP BY report_id 
HAVING count(report_id) > 2);

相关问题