Skip to content

Precision of numeric columns is not set correctly for TVP with multiple rows #211

Closed
@jneubecker

Description

There is a bug with inserting numeric or decimal values with a table valued parameter in the way precision is being set. For example when inserting 2 rows into a table with a numeric(6,3) column, if the value in the first row for the numeric column is 12.12 and the value for the same column in the second row is 1.123 the precision and scale in SQLServerDataTable for that column are set to 4 and 3. And when the metadata is populated in TVP.populateMetadataFromTable the precision and scale are then set to 4 and 3 for that column. But 12.12 is not a valid numeric(4,3). In SQLServerDataTable the precision should be set to the maximum of the precision to the left plus the maximum of the precision right of the decimal point between all values for a column. One way to do this would be to increase the precision when the scale is increased by the difference of the old and new scale.

Given the table:

CREATE TABLE [dbo].[TEST_TABLE](
	[id] [numeric](18, 0) NOT NULL,
	[number] [numeric](6, 3) NULL
)

And the table type:

CREATE TYPE [dbo].[testTableType] AS TABLE(
	[id] [numeric](18, 0) NULL,
	[number] [numeric](6, 3) NULL,
)

The following code will reproduce the error:

try (SQLServerPreparedStatement preparedStatement = (SQLServerPreparedStatement) conn.prepareStatement(“insert into TEST_TABLE (id, number) select TMP1.id, TMP1.number from ? as TMP1”)) {
      SQLServerDataTable dataTable = new SQLServerDataTable();

      dataTable.addColumnMetadata(“id”, java.sql.Types.NUMERIC);
      dataTable.addColumnMetadata(“number”, java.sql.Types.NUMERIC);

      dataTable.addRow(1, 12.12);
      dataTable.addRow(2, 1.123);

      preparedStatement.setStructured(1, “testTableType”, dataTable);

      preparedStatement.execute();
}
com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 1 (""), row 1, column 2: The supplied value is not a valid instance of data type numeric. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions