SQL JDB сервера C: десятичный параметр OUTPUT хранимой процедуры возвращает неправильное значение - PullRequest
1 голос
/ 21 марта 2020

SQL сервер JDB C: десятичный параметр OUTPUT хранимой процедуры возвращает целое число. Например,

create procedure foo(@minValue decimal(10,2) OUTPUT) as
begin 
    select @minValue = min(value) from Foo;
end;

create Table Foo (id int, value decimal(10,2));
insert into Foo(id,value) values (1, 12345.50);

JDB C:

CallableStatement statement = connection.prepareCall("{call foo(?)}");
statement.registerOutParameter("minValue", java.sql.Types.DECIMAL);
statement.execute();
BigDecimal value = statement.getObject("minValue");  <---- return 12345(Integer), not decimal 12345.50

Работает для суммы (значения), которая возвращает BigDecimal.

create procedure foo(@sumValue decimal(10,2) OUTPUT) as
begin 
    select @sumValue = sum(value) from Foo;
end;

1 Ответ

0 голосов
/ 21 марта 2020

Я все еще думаю, что вам нужно указать параметр масштаба, например: statement.registerOutParameter("minValue", java.sql.Types.DECIMAL, 2);

Вот пример SQL Настройка сервера 2017 в Docker ...

#!/usr/bin/env bash
docker pull microsoft/mssql-server-linux:2017-latest
docker run --name q60782511 -e 'HOMEBREW_NO_ENV_FILTERING=1' -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=myStrongP4ssw0rd' -p 1433:1433 -d microsoft/mssql-server-linux
docker exec -it q60782511 /opt/mssql-tools/bin/sqlcmd \
   -S localhost -U "sa" -P "myStrongP4ssw0rd" \
   -Q "use master
go
create database StackOverflow
go
use StackOverflow
go
create Table dbo.Foo (
  id int,
  value decimal(10,2)
);
insert into dbo.Foo (id, value) values
  (1, 12345.50);
go
create procedure dbo.minFoo(@minValue decimal(10,2) OUTPUT) as
begin 
    select @minValue = min(value) from dbo.Foo;
end;
go
create procedure dbo.sumFoo(@sumValue decimal(10,2) OUTPUT) as
begin 
    select @sumValue = sum(value) from dbo.Foo;
end;
go
declare @minValue decimal(10, 2), @sumValue decimal(10,2);
exec minFoo @minValue output;
exec sumFoo @sumValue output;
select @minValue, @sumValue;
go"

Какие выходы ...

Changed database context to 'master'.
Changed database context to 'StackOverflow'.

(1 rows affected)

------------ ------------
    12345.50     12345.50

(1 rows affected)

Затем в Java ...

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class q60782511 {
    public static void minFoo(Connection connection) throws SQLException {
        CallableStatement statement = connection.prepareCall("{call dbo.minFoo(?)}");
        statement.registerOutParameter("minValue", java.sql.Types.DECIMAL, 2);
        statement.execute();
        BigDecimal minValue = (BigDecimal) statement.getObject("minValue");
        System.out.println(String.format("minValue = %s", minValue));
    }

    public static void sumFoo(Connection connection) throws SQLException {
        CallableStatement statement = connection.prepareCall("{call dbo.sumFoo(?)}");
        statement.registerOutParameter("sumValue", java.sql.Types.DECIMAL, 2);
        statement.execute();
        BigDecimal sumValue = (BigDecimal) statement.getObject("sumValue");
        System.out.println(String.format("sumValue = %s", sumValue));
    }

    public static void main(String[] args) {
        String url = "jdbc:sqlserver://localhost:1433;databaseName=StackOverflow;user=sa;password=myStrongP4ssw0rd";
        try {
            // library reference: lib/mssql-jdbc-8.2.0.jre8.jar
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            Connection connection = DriverManager.getConnection(url);
            minFoo(connection);
            sumFoo(connection);
            connection.close();
        } catch (Exception e) {
            System.err.println(e.toString());
            System.exit(1);
        }
    }
}

Какие выходы ...

minValue = 12345.50
sumValue = 12345.50
...