diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java b/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java index 858111ca9..5d97369f3 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java @@ -415,7 +415,7 @@ void setValue(JDBCType jdbcType, Object value, JavaType javaType, StreamSetterAr // the value with the appropriate corresponding Unicode type. // JavaType.OBJECT == javaType when calling setNull() if (con.sendStringParametersAsUnicode() && (JavaType.STRING == javaType || JavaType.READER == javaType - || JavaType.CLOB == javaType || JavaType.OBJECT == javaType)) { + || JavaType.CLOB == javaType || JavaType.OBJECT == javaType) && jdbcType != JDBCType.VARCHAR) { jdbcType = getSSPAUJDBCType(jdbcType); } @@ -423,10 +423,14 @@ void setValue(JDBCType jdbcType, Object value, JavaType javaType, StreamSetterAr newDTV.setValue(con.getDatabaseCollation(), jdbcType, value, javaType, streamSetterArgs, calendar, scale, con, forceEncrypt); - if (!con.sendStringParametersAsUnicode()) { + if (!con.sendStringParametersAsUnicode() || (con.sendStringParametersAsUnicode() && jdbcType == JDBCType.VARCHAR)) { newDTV.sendStringParametersAsUnicode = false; } + if (con.sendStringParametersAsUnicode() && jdbcType == JDBCType.VARCHAR && (!con.getDatabaseCollation().isUtf8Encoding() || con.getServerMajorVersion() < 15)) { + throw new SQLServerException(SQLServerException.getErrString("R_possibleColumnDataCorruption"), null); + } + inputDTV = setterDTV = newDTV; } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLCollation.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLCollation.java index e7369bfe1..afafe80da 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLCollation.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLCollation.java @@ -56,6 +56,10 @@ final boolean hasAsciiCompatibleSBCS() { return encoding.hasAsciiCompatibleSBCS(); } + boolean isUtf8Encoding() { + return encoding.equals(Encoding.UTF8); + } + static final int tdsLength() { return TDS_LENGTH; } // Length of collation in TDS (in bytes) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java index 9055e9add..d5d73c3f4 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java @@ -165,6 +165,7 @@ protected Object[][] getContents() { {"R_invalidDatetimeType", "The datetimeType connection property {0} is not valid."}, {"R_dataAlreadyAccessed", "The data has been accessed and is not available for this column or parameter."}, {"R_outParamsNotPermittedinBatch", "The OUT and INOUT parameters are not permitted in a batch."}, + {"R_possibleColumnDataCorruption", "Attempted to insert encrypted unicode data into non-unicode column. Data corruption may occur."}, {"R_colNotMatchTable", "Number of provided columns {0} does not match the table definition {1}."}, {"R_invalidSQL", "Invalid SQL query {0}."}, {"R_multipleQueriesNotAllowed", "Multiple queries are not allowed."},