|
18 | 18 | import java.sql.Statement;
|
19 | 19 | import java.sql.Time;
|
20 | 20 | import java.sql.Timestamp;
|
| 21 | +import java.time.LocalDateTime; |
| 22 | +import java.time.LocalTime; |
| 23 | +import java.time.OffsetDateTime; |
21 | 24 | import java.time.ZoneId;
|
| 25 | +import java.time.ZoneOffset; |
22 | 26 | import java.util.ArrayList;
|
23 | 27 | import java.util.Arrays;
|
24 | 28 | import java.util.Calendar;
|
@@ -832,6 +836,221 @@ public void testNoSpaceInsert() throws Exception {
|
832 | 836 | }
|
833 | 837 | }
|
834 | 838 |
|
| 839 | + /** |
| 840 | + * Test bulk insert with all temporal types and money as varchar when useBulkCopyForBatchInsert is true. |
| 841 | + * sendTemporalDataTypesAsStringForBulkCopy is set to true by default. |
| 842 | + * Temporal types are sent as varchar, and money/smallMoney are sent as their respective types. |
| 843 | + * |
| 844 | + * @throws Exception |
| 845 | + */ |
| 846 | + @Test |
| 847 | + @Tag(Constants.xAzureSQLDW) |
| 848 | + public void testBulkInsertWithAllTemporalTypesAndMoneyAsVarchar() throws Exception { |
| 849 | + String tableName = RandomUtil.getIdentifier("BulkTable"); |
| 850 | + String createTableSQL = "CREATE TABLE " + AbstractSQLGenerator.escapeIdentifier(tableName) + " (" + |
| 851 | + "dateTimeColumn DATETIME, " + |
| 852 | + "smallDateTimeColumn SMALLDATETIME, " + |
| 853 | + "dateTime2Column DATETIME2, " + |
| 854 | + "dateColumn DATE, " + |
| 855 | + "timeColumn TIME, " + |
| 856 | + "dateTimeOffsetColumn DATETIMEOFFSET, " + |
| 857 | + "moneyColumn MONEY, " + |
| 858 | + "smallMoneyColumn SMALLMONEY" + ")"; |
| 859 | + String insertSQL = "INSERT INTO " + AbstractSQLGenerator.escapeIdentifier(tableName) + |
| 860 | + " (dateTimeColumn, smallDateTimeColumn, dateTime2Column, dateColumn, timeColumn, dateTimeOffsetColumn, moneyColumn, smallMoneyColumn) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; |
| 861 | + String selectSQL = "SELECT dateTimeColumn, smallDateTimeColumn, dateTime2Column, dateColumn, timeColumn, dateTimeOffsetColumn, moneyColumn, smallMoneyColumn FROM " |
| 862 | + + AbstractSQLGenerator.escapeIdentifier(tableName); |
| 863 | + |
| 864 | + try (Connection connection = PrepUtil.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;"); |
| 865 | + Statement stmt = connection.createStatement(); |
| 866 | + SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection.prepareStatement(insertSQL)) { |
| 867 | + |
| 868 | + // Drop and create table |
| 869 | + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt); |
| 870 | + stmt.execute(createTableSQL); |
| 871 | + |
| 872 | + Timestamp dateTimeVal = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 45)); |
| 873 | + String expectedDateTimeString = "2025-05-13 14:30:45.0"; |
| 874 | + |
| 875 | + Timestamp smallDateTimeVal = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 45)); |
| 876 | + String expectedSmallDateTimeString = "2025-05-13 14:31:00.0"; |
| 877 | + |
| 878 | + Timestamp dateTime2Val = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 25, 123000000)); |
| 879 | + String expectedDateTime2String = "2025-05-13 14:30:25.1230000"; |
| 880 | + |
| 881 | + Date dateVal = Date.valueOf("2025-06-02"); |
| 882 | + String expectedDateString = "2025-06-02"; |
| 883 | + |
| 884 | + Time timeVal = Time.valueOf("14:30:00"); |
| 885 | + String expectedTimeString = "14:30:00"; |
| 886 | + |
| 887 | + OffsetDateTime offsetDateTimeVal = OffsetDateTime.of(2025, 5, 13, 14, 30, 0, 0, ZoneOffset.UTC); |
| 888 | + DateTimeOffset dateTimeOffsetVal = DateTimeOffset.valueOf(offsetDateTimeVal); |
| 889 | + String expectedDateTimeOffsetString = "2025-05-13 14:30:00 +00:00"; |
| 890 | + |
| 891 | + BigDecimal moneyVal = new BigDecimal("12345.6789"); |
| 892 | + String expectedMoneyString = "12345.6789"; |
| 893 | + |
| 894 | + BigDecimal smallMoneyVal = new BigDecimal("1234.5611"); |
| 895 | + String expectedSmallMoneyString = "1234.5611"; |
| 896 | + |
| 897 | + pstmt.setTimestamp(1, dateTimeVal); // DATETIME |
| 898 | + pstmt.setSmallDateTime(2, smallDateTimeVal); // SMALLDATETIME |
| 899 | + pstmt.setObject(3, dateTime2Val); // DATETIME2 |
| 900 | + pstmt.setDate(4, dateVal); // DATE |
| 901 | + pstmt.setObject(5, timeVal); // TIME |
| 902 | + pstmt.setDateTimeOffset(6, dateTimeOffsetVal); // DATETIMEOFFSET |
| 903 | + pstmt.setMoney(7, moneyVal); // MONEY |
| 904 | + pstmt.setSmallMoney(8, smallMoneyVal); // SMALLMONEY |
| 905 | + |
| 906 | + pstmt.addBatch(); |
| 907 | + pstmt.executeBatch(); |
| 908 | + |
| 909 | + // Validate inserted data |
| 910 | + try (ResultSet rs = stmt.executeQuery(selectSQL)) { |
| 911 | + assertTrue(rs.next()); |
| 912 | + |
| 913 | + assertEquals(dateTimeVal, rs.getTimestamp(1)); |
| 914 | + assertEquals(expectedDateTimeString, rs.getString(1)); |
| 915 | + |
| 916 | + assertEquals(Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 31, 0)), rs.getTimestamp(2)); |
| 917 | + assertEquals(expectedSmallDateTimeString, rs.getString(2)); |
| 918 | + |
| 919 | + assertEquals(dateTime2Val, rs.getTimestamp(3)); |
| 920 | + assertEquals(expectedDateTime2String, rs.getString(3)); |
| 921 | + |
| 922 | + assertEquals(dateVal, rs.getDate(4)); |
| 923 | + assertEquals(expectedDateString, rs.getString(4)); |
| 924 | + |
| 925 | + assertEquals(timeVal, rs.getObject(5)); |
| 926 | + assertEquals(expectedTimeString, rs.getObject(5).toString()); |
| 927 | + |
| 928 | + assertEquals(dateTimeOffsetVal, rs.getObject(6, DateTimeOffset.class)); |
| 929 | + assertEquals(expectedDateTimeOffsetString, rs.getObject(6).toString()); |
| 930 | + |
| 931 | + assertEquals(moneyVal, rs.getBigDecimal(7)); |
| 932 | + assertEquals(expectedMoneyString, rs.getBigDecimal(7).toString()); |
| 933 | + |
| 934 | + assertEquals(smallMoneyVal, rs.getBigDecimal(8)); |
| 935 | + assertEquals(expectedSmallMoneyString,rs.getBigDecimal(8).toString()); |
| 936 | + |
| 937 | + } |
| 938 | + } finally { |
| 939 | + try (Statement stmt = connection.createStatement()) { |
| 940 | + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt); |
| 941 | + } |
| 942 | + } |
| 943 | + } |
| 944 | + |
| 945 | + /** |
| 946 | + * Test bulk insert with all temporal types and money as varchar when useBulkCopyForBatchInsert is true. |
| 947 | + * and sendTemporalDataTypesAsStringForBulkCopy is set to false explicitly. |
| 948 | + * In this case all data types are sent as their respective types, including temporal types and money/smallMoney. |
| 949 | + * |
| 950 | + * @throws Exception |
| 951 | + */ |
| 952 | + @Test |
| 953 | + @Tag(Constants.xAzureSQLDW) |
| 954 | + public void testBulkInsertWithAllTemporalTypesAndMoney() throws Exception { |
| 955 | + String tableName = RandomUtil.getIdentifier("BulkTable"); |
| 956 | + String createTableSQL = "CREATE TABLE " + AbstractSQLGenerator.escapeIdentifier(tableName) + " (" + |
| 957 | + "dateTimeColumn DATETIME, " + |
| 958 | + "smallDateTimeColumn SMALLDATETIME, " + |
| 959 | + "dateTime2Column DATETIME2, " + |
| 960 | + "dateColumn DATE, " + |
| 961 | + "timeColumn TIME, " + |
| 962 | + "dateTimeOffsetColumn DATETIMEOFFSET, " + |
| 963 | + "moneyColumn MONEY, " + |
| 964 | + "smallMoneyColumn SMALLMONEY" + ")"; |
| 965 | + String insertSQL = "INSERT INTO " + AbstractSQLGenerator.escapeIdentifier(tableName) + |
| 966 | + " (dateTimeColumn, smallDateTimeColumn, dateTime2Column, dateColumn, timeColumn, dateTimeOffsetColumn, moneyColumn, smallMoneyColumn) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; |
| 967 | + String selectSQL = "SELECT dateTimeColumn, smallDateTimeColumn, dateTime2Column, dateColumn, timeColumn, dateTimeOffsetColumn, moneyColumn, smallMoneyColumn FROM " |
| 968 | + + AbstractSQLGenerator.escapeIdentifier(tableName); |
| 969 | + |
| 970 | + try (Connection connection = PrepUtil.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); |
| 971 | + Statement stmt = connection.createStatement(); |
| 972 | + SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) connection.prepareStatement(insertSQL)) { |
| 973 | + |
| 974 | + // Drop and create table |
| 975 | + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt); |
| 976 | + stmt.execute(createTableSQL); |
| 977 | + |
| 978 | + Timestamp dateTimeVal = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 45)); |
| 979 | + String expectedDateTimeString = "2025-05-13 14:30:45.0"; |
| 980 | + |
| 981 | + Timestamp smallDateTimeVal = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 45)); |
| 982 | + String expectedSmallDateTimeString = "2025-05-13 14:31:00.0"; |
| 983 | + |
| 984 | + Timestamp dateTime2Val = Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 30, 25, 123000000)); |
| 985 | + String expectedDateTime2String = "2025-05-13 14:30:25.1230000"; |
| 986 | + |
| 987 | + Date dateVal = Date.valueOf("2025-06-02"); |
| 988 | + String expectedDateString = "2025-06-02"; |
| 989 | + |
| 990 | + LocalTime time = LocalTime.of(14, 30, 0); |
| 991 | + Timestamp timeVal = Timestamp.valueOf( |
| 992 | + LocalDateTime.of(1970, 1, 1, time.getHour(), time.getMinute(), time.getSecond())); |
| 993 | + pstmt.setTimestamp(5, timeVal); |
| 994 | + String expectedTimeString = "14:30:00"; |
| 995 | + |
| 996 | + OffsetDateTime offsetDateTimeVal = OffsetDateTime.of(2025, 5, 13, 14, 30, 0, 0, ZoneOffset.UTC); |
| 997 | + DateTimeOffset dateTimeOffsetVal = DateTimeOffset.valueOf(offsetDateTimeVal); |
| 998 | + String expectedDateTimeOffsetString = "2025-05-13 14:30:00 +00:00"; |
| 999 | + |
| 1000 | + BigDecimal moneyVal = new BigDecimal("12345.6789"); |
| 1001 | + String expectedMoneyString = "12345.6789"; |
| 1002 | + |
| 1003 | + BigDecimal smallMoneyVal = new BigDecimal("1234.5611"); |
| 1004 | + String expectedSmallMoneyString = "1234.5611"; |
| 1005 | + |
| 1006 | + pstmt.setTimestamp(1, dateTimeVal); // DATETIME |
| 1007 | + pstmt.setSmallDateTime(2, smallDateTimeVal); // SMALLDATETIME |
| 1008 | + pstmt.setObject(3, dateTime2Val); // DATETIME2 |
| 1009 | + pstmt.setDate(4, dateVal); // DATE |
| 1010 | + pstmt.setTimestamp(5, timeVal); // TIME |
| 1011 | + pstmt.setDateTimeOffset(6, dateTimeOffsetVal); // DATETIMEOFFSET |
| 1012 | + pstmt.setMoney(7, moneyVal); // MONEY |
| 1013 | + pstmt.setSmallMoney(8, smallMoneyVal); // SMALLMONEY |
| 1014 | + |
| 1015 | + pstmt.addBatch(); |
| 1016 | + pstmt.executeBatch(); |
| 1017 | + |
| 1018 | + // Validate inserted data |
| 1019 | + try (ResultSet rs = stmt.executeQuery(selectSQL)) { |
| 1020 | + assertTrue(rs.next()); |
| 1021 | + |
| 1022 | + assertEquals(dateTimeVal, rs.getTimestamp(1)); |
| 1023 | + assertEquals(expectedDateTimeString, rs.getString(1)); |
| 1024 | + |
| 1025 | + assertEquals(Timestamp.valueOf(LocalDateTime.of(2025, 5, 13, 14, 31, 0)), rs.getTimestamp(2)); |
| 1026 | + assertEquals(expectedSmallDateTimeString, rs.getString(2)); |
| 1027 | + |
| 1028 | + assertEquals(dateTime2Val, rs.getTimestamp(3)); |
| 1029 | + assertEquals(expectedDateTime2String, rs.getString(3)); |
| 1030 | + |
| 1031 | + assertEquals(dateVal, rs.getDate(4)); |
| 1032 | + assertEquals(expectedDateString, rs.getString(4)); |
| 1033 | + |
| 1034 | + assertEquals(Time.valueOf(time), rs.getObject(5)); |
| 1035 | + assertEquals(expectedTimeString, rs.getObject(5).toString()); |
| 1036 | + |
| 1037 | + assertEquals(dateTimeOffsetVal, rs.getObject(6, DateTimeOffset.class)); |
| 1038 | + assertEquals(expectedDateTimeOffsetString, rs.getObject(6).toString()); |
| 1039 | + |
| 1040 | + assertEquals(moneyVal, rs.getBigDecimal(7)); |
| 1041 | + assertEquals(expectedMoneyString, rs.getBigDecimal(7).toString()); |
| 1042 | + |
| 1043 | + assertEquals(smallMoneyVal, rs.getBigDecimal(8)); |
| 1044 | + assertEquals(expectedSmallMoneyString,rs.getBigDecimal(8).toString()); |
| 1045 | + |
| 1046 | + } |
| 1047 | + } finally { |
| 1048 | + try (Statement stmt = connection.createStatement()) { |
| 1049 | + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt); |
| 1050 | + } |
| 1051 | + } |
| 1052 | + } |
| 1053 | + |
835 | 1054 | @BeforeAll
|
836 | 1055 | public static void setupTests() throws Exception {
|
837 | 1056 | setConnection();
|
|
0 commit comments