From 812aecc117569680de8ce2e959af86ec85264809 Mon Sep 17 00:00:00 2001 From: Afsaneh Rafighi Date: Tue, 8 Aug 2017 14:39:59 -0700 Subject: [PATCH] Add datetime/smalldatetime support for tvp Merge branch 'dev' of https://github.com/Microsoft/mssql-jdbc into tvpDatetimeSmallDateTime # Conflicts: # src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java # src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java --- .../microsoft/sqlserver/jdbc/IOBuffer.java | 4 + .../sqlserver/jdbc/SQLServerDataTable.java | 2 + .../sqlserver/jdbc/tvp/TVPTypesTest.java | 110 ++++++++++++++---- 3 files changed, 93 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java index 01ad48256..223befefe 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java @@ -4863,6 +4863,8 @@ private void writeInternalTVPRowValues(JDBCType jdbcType, case TIME: case TIMESTAMP: case DATETIMEOFFSET: + case DATETIME: + case SMALLDATETIME: case TIMESTAMP_WITH_TIMEZONE: case TIME_WITH_TIMEZONE: case CHAR: @@ -5102,6 +5104,8 @@ void writeTVPColumnMetaData(TVP value) throws SQLServerException { case TIME: case TIMESTAMP: case DATETIMEOFFSET: + case DATETIME: + case SMALLDATETIME: case TIMESTAMP_WITH_TIMEZONE: case TIME_WITH_TIMEZONE: case CHAR: diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java index f1436ceb5..53284f372 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java @@ -218,6 +218,8 @@ private void internalAddrow(JDBCType jdbcType, case TIME: case TIMESTAMP: case DATETIMEOFFSET: + case DATETIME: + case SMALLDATETIME: // Sending temporal types as string. Error from database is thrown if parsing fails // no need to send precision for temporal types, string literal will never exceed DataTypes.SHORT_VARTYPE_MAX_BYTES diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPTypesTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPTypesTest.java index 01195e36e..5d4ec875c 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPTypesTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/tvp/TVPTypesTest.java @@ -27,6 +27,7 @@ import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement; import com.microsoft.sqlserver.jdbc.SQLServerDataTable; import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; +import com.microsoft.sqlserver.jdbc.SQLServerResultSet; import com.microsoft.sqlserver.testframework.AbstractTest; @RunWith(JUnitPlatform.class) @@ -36,8 +37,8 @@ public class TVPTypesTest extends AbstractTest { static Statement stmt = null; static ResultSet rs = null; static SQLServerDataTable tvp = null; - private static String tvpName = "MaxTypesTVP"; - private static String charTable = "MaxTypesTVPTable"; + private static String tvpName = "TVP"; + private static String table = "TVPTable"; private static String procedureName = "procedureThatCallsTVP"; private String value = null; @@ -61,12 +62,12 @@ public void testLongVarchar() throws SQLException { tvp.addRow(value); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); - rs = conn.createStatement().executeQuery("select * from " + charTable); + rs = conn.createStatement().executeQuery("select * from " + table); while (rs.next()) { assertEquals(rs.getString(1), value); } @@ -95,12 +96,12 @@ public void testLongNVarchar() throws SQLException { tvp.addRow(value); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); - rs = conn.createStatement().executeQuery("select * from " + charTable); + rs = conn.createStatement().executeQuery("select * from " + table); while (rs.next()) { assertEquals(rs.getString(1), value); } @@ -128,13 +129,13 @@ public void testXML() throws SQLException { tvp.addRow(value); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); Connection con = DriverManager.getConnection(connectionString); - ResultSet rs = con.createStatement().executeQuery("select * from " + charTable); + ResultSet rs = con.createStatement().executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); @@ -161,13 +162,13 @@ public void testnText() throws SQLException { tvp.addRow(value); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); Connection con = DriverManager.getConnection(connectionString); - ResultSet rs = con.createStatement().executeQuery("select * from " + charTable); + ResultSet rs = con.createStatement().executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); @@ -194,13 +195,13 @@ public void testText() throws SQLException { tvp.addRow(value); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); Connection con = DriverManager.getConnection(connectionString); - ResultSet rs = con.createStatement().executeQuery("select * from " + charTable); + ResultSet rs = con.createStatement().executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); @@ -227,13 +228,13 @@ public void testImage() throws SQLException { tvp.addRow(value.getBytes()); SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection - .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); pstmt.setStructured(1, tvpName, tvp); pstmt.execute(); Connection con = DriverManager.getConnection(connectionString); - ResultSet rs = con.createStatement().executeQuery("select * from " + charTable); + ResultSet rs = con.createStatement().executeQuery("select * from " + table); while (rs.next()) assertTrue(parseByte(rs.getBytes(1), value.getBytes())); @@ -269,7 +270,7 @@ public void testTVPLongVarcharStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); @@ -303,7 +304,7 @@ public void testTVPLongNVarcharStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); @@ -337,7 +338,7 @@ public void testTVPXMLStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); if (null != P_C_statement) { @@ -371,7 +372,7 @@ public void testTVPTextStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); if (null != P_C_statement) { @@ -405,7 +406,7 @@ public void testTVPNTextStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertEquals(rs.getString(1), value); if (null != P_C_statement) { @@ -439,14 +440,77 @@ public void testTVPImageStoredProcedure() throws SQLException { P_C_statement.setStructured(1, tvpName, tvp); P_C_statement.execute(); - rs = stmt.executeQuery("select * from " + charTable); + rs = stmt.executeQuery("select * from " + table); while (rs.next()) assertTrue(parseByte(rs.getBytes(1), value.getBytes())); if (null != P_C_statement) { P_C_statement.close(); } } + + /** + * Test a datetime support + * + * @throws SQLException + */ + @Test + public void testDateTime() throws SQLException { + createTables("datetime"); + createTVPS("datetime"); + + java.sql.Timestamp value = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.123"); + tvp = new SQLServerDataTable(); + tvp.addColumnMetadata("c1", microsoft.sql.Types.DATETIME); + tvp.addRow(value); + + SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); + pstmt.setStructured(1, tvpName, tvp); + + pstmt.execute(); + + rs = conn.createStatement().executeQuery("select * from " + table); + while (rs.next()) { + assertEquals(((SQLServerResultSet) rs).getDateTime(1), value); + } + if (null != pstmt) { + pstmt.close(); + } + } + + /** + * Test a smalldatetime support + * + * @throws SQLException + */ + @Test + public void testSmallDateTime() throws SQLException { + createTables("smalldatetime"); + createTVPS("smalldatetime"); + + java.sql.Timestamp value = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.123"); + java.sql.Timestamp returnValue = java.sql.Timestamp.valueOf("2007-09-23 10:10:00.0"); + + tvp = new SQLServerDataTable(); + tvp.addColumnMetadata("c1", microsoft.sql.Types.SMALLDATETIME); + tvp.addRow(value); + + SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection + .prepareStatement("INSERT INTO " + table + " select * from ? ;"); + pstmt.setStructured(1, tvpName, tvp); + + pstmt.execute(); + + rs = conn.createStatement().executeQuery("select * from " + table); + while (rs.next()) { + assertEquals(((SQLServerResultSet) rs).getSmallDateTime(1), returnValue); + } + if (null != pstmt) { + pstmt.close(); + } + } + @BeforeEach private void testSetup() throws SQLException { conn = DriverManager.getConnection(connectionString); @@ -473,7 +537,7 @@ private static void dropProcedure() throws SQLException { } private static void dropTables() throws SQLException { - stmt.executeUpdate("if object_id('" + charTable + "','U') is not null" + " drop table " + charTable); + stmt.executeUpdate("if object_id('" + table + "','U') is not null" + " drop table " + table); } private static void dropTVPS() throws SQLException { @@ -481,14 +545,14 @@ private static void dropTVPS() throws SQLException { } private static void createPreocedure() throws SQLException { - String sql = "CREATE PROCEDURE " + procedureName + " @InputData " + tvpName + " READONLY " + " AS " + " BEGIN " + " INSERT INTO " + charTable + String sql = "CREATE PROCEDURE " + procedureName + " @InputData " + tvpName + " READONLY " + " AS " + " BEGIN " + " INSERT INTO " + table + " SELECT * FROM @InputData" + " END"; stmt.execute(sql); } private void createTables(String colType) throws SQLException { - String sql = "create table " + charTable + " (c1 " + colType + " null);"; + String sql = "create table " + table + " (c1 " + colType + " null);"; stmt.execute(sql); }