开发者社区> 问答> 正文

而不是INSERT触发器被绕过

我有一个表,其中有一个列,该列tripNumber不应重复。

我知道,我可以更改表并创建该列,unique但是由于某种原因,我无法更改该表,因为它已经在生产中。因此,我编写了以下触发器,基本上可以完成相同的操作。

USE [cst_abc]
GO

/****** Object:  Trigger [dbo].[checkTripNumber]    Script Date: 12/21/2019 18:37:10 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE trigger [dbo].[checkTripNumber] on [dbo].[tripDetails]
instead of insert
as 
begin
if exists(select * from [dbo].[tripDetails] where tripNumber = (select [tripNumber] from inserted i))
RAISERROR ('Trip is already there.',15,0);
else
INSERT INTO [cst_abc].[dbo].[tripDetails]
           ([tripNumber]
           ,[noW]
           ,[EndTime]
           ,[someText]
           ,[totalInput]
           ,[totalOutput]
           ,[Difference]
           ,[start]
           ,[end]
           ,[StartTime]
           ,[EndTime]
           ,[serverSync])
SELECT[tripNumber],[noW],[EndTime]
           ,[someText]
           ,[totalInput]
           ,[totalOutput]
           ,[Difference]
           ,[start]
           ,[end]
           ,[StartTime]
           ,[EndTime]
           ,[serverSync] from inserted i
end
GO

它确实按预期工作。我写了一个小的Java代码,它基本上启动了一个新线程并尝试插入行。我要做的是先检查行程是否存在,如果是,则不执行任何操作,否则插入具有特定ID的新行。

public static void startThread()
    {
        new Thread(() -> {
            try {
                showTimeInMilli("FuncA");
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }).start();
        new Thread(() -> {
            try {
                showTimeInMilli("FuncB");
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }).start();

    }

public static void showTimeInMilli(String name) throws SQLException
    {
        System.out.println("called from "+name +"Current time is "+System.currentTimeMillis());
        if(checkTripNumber(1))
        {
                System.out.println("called from "+name +" and trip exists.");
        }
        else
        {
            System.out.println("called from "+name +" and inserting new row.");
            SqlUtil.startNewTrip(1,7,"ap1","2019-06-18 07:06:00",5,1576631560);
        }
    }

这里要注意的一点是,该触发器即startTrip可以从多个源触发,并且我已经看到大多数时候它是同时触发的(epoch例如,我从两个源中准确地存储了它被触发的时间1576934304)

问题

在预期的10倍中有9倍,即它不让新行添加,但有时会添加重复行tripNumber。非常感谢您的帮助。

上面的Java代码的理想日志是:

called from FuncACurrent time is 1576933097423
called from FuncBCurrent time is 1576933097423
td before sendig false
called from FuncB and inserting new row.
td before sendig false
called from FuncA and inserting new row.
com.microsoft.sqlserver.jdbc.SQLServerException: Trip is already there.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1655)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:440)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:385)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7505)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2445)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:191)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:166)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:367)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
    at database.SqlUtil.startNewTrip(SqlUtil.java:45)
    at database.Hikari.showTimeInMilli(Hikari.java:122)
    at database.Hikari.lambda$0(Hikari.java:44)
    at java.lang.Thread.run(Unknown Source)
SQL Exception2 com.microsoft.sqlserver.jdbc.SQLServerException: Trip is already there.

意外的日志是:

called from FuncACurrent time is 1576933097323
called from FuncBCurrent time is 1576933097323
td before sendig false
called from FuncB and inserting new row.
td before sendig false
called from FuncA and inserting new row.

展开
收起
心有灵_夕 2019-12-22 14:17:32 709 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载