From 04f7b9398e69be7bc6ffebe44a279b03655012b1 Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Wed, 23 Aug 2017 13:14:05 -0700 Subject: [PATCH 1/2] Throw the initial batch exception --- .../sqlserver/jdbc/SQLServerPreparedStatement.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java index 2b9350e49..c54f1d436 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java @@ -2683,10 +2683,15 @@ final void doExecutePreparedStatementBatch(PrepStmtBatchExecCmd batchCommand) th numBatchesPrepared = numBatchesExecuted; continue; } - else + else if (null != batchCommand.batchException) { + // if batch exception occurred, loop out to throw the initial batchException + continue; + } + else { throw e; + } } - break; + break; } } } From 1892ee184d128ce3b55ff08a908e8be08f56528f Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Mon, 28 Aug 2017 13:50:01 -0700 Subject: [PATCH 2/2] updated test file --- .../jdbc/SQLServerPreparedStatement.java | 2 + .../jdbc/unit/statement/BatchTriggerTest.java | 161 ++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchTriggerTest.java diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java index c54f1d436..2e47eb042 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java @@ -2685,6 +2685,8 @@ final void doExecutePreparedStatementBatch(PrepStmtBatchExecCmd batchCommand) th } else if (null != batchCommand.batchException) { // if batch exception occurred, loop out to throw the initial batchException + numBatchesExecuted = numBatchesPrepared; + attempt++; continue; } else { diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchTriggerTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchTriggerTest.java new file mode 100644 index 000000000..1abcf471c --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchTriggerTest.java @@ -0,0 +1,161 @@ +/* + * Microsoft JDBC Driver for SQL Server + * + * Copyright(c) Microsoft Corporation All rights reserved. + * + * This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ +package com.microsoft.sqlserver.jdbc.unit.statement; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.opentest4j.TestAbortedException; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import com.microsoft.sqlserver.jdbc.SQLServerStatement; +import com.microsoft.sqlserver.testframework.AbstractTest; +import com.microsoft.sqlserver.testframework.Utils; + +/** + * Tests batch execution with trigger exception + * + */ +@RunWith(JUnitPlatform.class) +public class BatchTriggerTest extends AbstractTest { + + static Statement stmt = null; + static Connection connection = null; + static String tableName = "triggerTable"; + static String triggerName = "triggerTest"; + static String customErrorMessage = "Custom error message, you should see me. col1 should be higher than 10"; + static String insertQuery = "insert into " + tableName + " (col1, col2, col3, col4) values (1, '22-08-2017 17:30:00.000', 'R4760', 31)"; + + /** + * Tests that the proper trigger exception is thrown using statement + * + * @throws SQLException + */ + @Test + public void statementTest() throws SQLException { + Statement stmt = null; + try { + stmt = connection.createStatement(); + stmt.addBatch(insertQuery); + stmt.executeBatch(); + fail("Trigger Exception not thrown"); + } + catch (Exception e) { + assertTrue(e.getMessage().equalsIgnoreCase(customErrorMessage)); + } + + finally { + if (stmt != null) { + stmt.close(); + } + } + } + + /** + * Tests that the proper trigger exception is thrown using preparedSatement + * + * @throws SQLException + */ + @Test + public void preparedStatementTest() throws SQLException { + PreparedStatement pstmt = null; + try { + pstmt = connection.prepareStatement(insertQuery); + pstmt.addBatch(); + pstmt.executeBatch(); + fail("Trigger Exception not thrown"); + } + catch (Exception e) { + + assertTrue(e.getMessage().equalsIgnoreCase(customErrorMessage)); + } + finally { + if (pstmt != null) { + pstmt.close(); + } + } + } + + /** + * Create the trigger + * + * @param triggerName + * @throws SQLException + */ + private static void createTrigger(String triggerName) throws SQLException { + String sql = "create trigger " + triggerName + " on " + tableName + " for insert " + "as " + "begin " + "if (select col1 from " + tableName + + ") > 10 " + "begin " + "return " + "end " + + "RAISERROR ('Custom error message, you should see me. col1 should be higher than 10', 16, 0) " + "rollback transaction " + "end"; + stmt.execute(sql); + } + + /** + * Creating tables + * + * @throws SQLException + */ + private static void createTable() throws SQLException { + String sql = "create table " + tableName + " ( col1 int, col2 varchar(50), col3 varchar(10), col4 int)"; + stmt.execute(sql); + } + + /** + * Setup test + * + * @throws TestAbortedException + * @throws Exception + */ + @BeforeAll + public static void testSetup() throws TestAbortedException, Exception { + connection = DriverManager.getConnection(connectionString); + stmt = (SQLServerStatement) connection.createStatement(); + stmt.execute("IF EXISTS (\r\n" + " SELECT *\r\n" + " FROM sys.objects\r\n" + " WHERE [type] = 'TR' AND [name] = '" + triggerName + + "'\r\n" + " )\r\n" + " DROP TRIGGER " + triggerName + ";"); + dropTable(); + createTable(); + createTrigger(triggerName); + } + + /** + * Drop the table + * + * @throws SQLException + */ + private static void dropTable() throws SQLException { + Utils.dropTableIfExists(tableName, stmt); + } + + /** + * Cleaning up + * + * @throws SQLException + */ + @AfterAll + public static void terminateVariation() throws SQLException { + dropTable(); + stmt.execute("IF EXISTS (\r\n" + " SELECT *\r\n" + " FROM sys.objects\r\n" + " WHERE [type] = 'TR' AND [name] = '" + triggerName + + "'\r\n" + " )\r\n" + " DROP TRIGGER " + triggerName + ";"); + + if (null != connection) { + connection.close(); + } + if (null != stmt) { + stmt.close(); + } + + } +} \ No newline at end of file