Java Hibernate拦截器-尝试捕获T-SQL
我需要在插入中忽略来自SQL Server的主键冲突。虽然有几种方法可以完成此任务,但其中许多方法都会影响性能或不可行。我需要批量插入到一个表中,有可能重复 为了完成这项任务,我编写了一个Hibernate拦截器,它拦截Java Hibernate拦截器-尝试捕获T-SQL,java,sql-server,hibernate,tsql,Java,Sql Server,Hibernate,Tsql,我需要在插入中忽略来自SQL Server的主键冲突。虽然有几种方法可以完成此任务,但其中许多方法都会影响性能或不可行。我需要批量插入到一个表中,有可能重复 为了完成这项任务,我编写了一个Hibernate拦截器,它拦截onPrepareStatement,并将Hibernate生成的SQL封装在t-SQL TRY-CATCH构造中。TRY-CATCH查找主键冲突并使其静音。下面是我的拦截器代码 private static final String FORMAT_TRY_CATCH = "BE
onPrepareStatement
,并将Hibernate生成的SQL封装在t-SQL TRY-CATCH构造中。TRY-CATCH查找主键冲突并使其静音。下面是我的拦截器代码
private static final String FORMAT_TRY_CATCH = "BEGIN TRY %s END TRY\r\n" + "BEGIN CATCH\r\n" + "\r\n"
+ "DECLARE @ErrorMessage NVARCHAR(4000),\r\n" + " @ErrorNumber INT,\r\n" + " @ErrorSeverity INT,\r\n" + " @ErrorState INT,\r\n"
+ " @ErrorLine INT,\r\n" + " @ErrorProcedure NVARCHAR(200) ;\r\n" + "\r\n"
+ "SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorSeverity = ERROR_SEVERITY(),\r\n"
+ " @ErrorState = ERROR_STATE(), @ErrorLine = ERROR_LINE(),\r\n"
+ " @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-') ;\r\n" + "\r\n"
+ "SELECT @ErrorMessage = N'Error %%d, Level %%d, State %%d, Procedure %%s, Line %%d, ' +\r\n"
+ " 'Message: ' + ERROR_MESSAGE() ;\r\n" + " IF @ErrorNumber <> 2627\r\n" + " BEGIN\r\n"
+ "RAISERROR (@ErrorMessage, @ErrorSeverity, 1, @ErrorNumber, -- parameter: original error number.\r\n"
+ " @ErrorSeverity, -- parameter: original error severity.\r\n" + " @ErrorState, -- parameter: original error state.\r\n"
+ " @ErrorProcedure, -- parameter: original error procedure name.\r\n"
+ " @ErrorLine-- parameter: original error line number.\r\n" + " ) ;\r\n" + " END\r\n" + "END CATCH;";
@Override
public String onPrepareStatement(String sql) {
if (sql.toLowerCase().startsWith("insert")) {
return String.format(FORMAT_TRY_CATCH, sql);
}
return sql;
}
当存在主键约束冲突时,此虚拟逻辑将降低性能。是否有一个性能更好的伪脚本,或者有更好的方法来捕获主键约束冲突
注意:出于性能原因,在每次插入之前进行选择是不可接受的。我无法重新创建SQL的主键以启用“忽略重复”键
DECLARE @dummy TABLE (col1 int)
INSERT INTO @dummy values (1)