Как передать значения пользовательской переменной типа данных в MS SQL из java, используя процедуру хранения spring jdbc

У меня есть процедура хранения MS SQL ниже с определяемой пользователем переменной (@Location

CREATE PROCEDURE [Organization].[Organization_Insert]   
(  
 @OrganizationID NVARCHAR(256),  
 @Location Locationtype ReadOnly
)

@Location имеет следующие атрибуты: OrganizationSubID, LocationCode.

Я использую приведенный ниже класс Java для вызова процедуры хранения,

class OrganizationInsertProcedure extends StoredProcedure {

  private final String[] outputParameters = new String[] {OUTPUT};

  public PlanActivityInsertProcedure(DataSource dataSource) {
    super(dataSource, "Organization_Insert");

    declareParameter(new SqlParameter("@OrganizationID", Types.NVARCHAR));
    declareParameter(new SqlParameter("@Location", Types.ARRAY, "Locationtype"));

    compile();
  }

Здесь мой вопрос: как построить переменную @Location из java и передать ее в базу данных MS SQL. (использую драйвер sqljdbc4.jar для подключения к базе данных)

Я целый день гуглил и перепробовал много реализаций и ничего не окупилось.

Пожалуйста, кто-нибудь, пролейте свет на это...


person J.P    schedule 13.11.2014    source источник
comment
Как именно определяется тип Locationtype? Пожалуйста, отредактируйте свой вопрос, включив в него оператор CREATE TYPE, который его создал.   -  person Luke Woodward    schedule 16.11.2014


Ответы (1)


(Я предполагаю, что вы объявили Locationtype в качестве табличной переменной. На это намекает использование ReadOnly в параметре хранимой процедуры.)

Согласно этому сообщению на форумах SQL Server, драйвер JDBC Microsoft SQL Server в настоящее время не поддерживает табличные переменные. Итак, похоже, вам нужно создать строку T-SQL, которая объявляет табличную переменную, вставляет данные в таблицу, а затем выполняет хранимую процедуру.

В «простом» JDBC, то есть без использования Spring, код для этого выглядит примерно так:

    int numRows = /* number of rows in table variable */;

    StringBuilder sqlBuilder = new StringBuilder("DECLARE @Location AS LocationType;");
    for (int i = 0; i < numRows; ++i) {
        sqlBuilder.append(
            "INSERT INTO @Location (OrganizationSubID, LocationCode) VALUES (?, ?);");
    }

    sqlBuilder.append("EXEC [Organization].[Organization_Insert] ?, @Location;");

    PreparedStatement stmt = connection.prepareStatement(sqlBuilder.toString());
    for (int i = 0; i < numRows; ++i) {
        stmt.setString(i * 2 + 1, /* OrganizationSubID for row i */);
        stmt.setString(i * 2 + 2, /* LocationCode for row i  */);
    }

    stmt.setString(numRows * 2 + 1, /* Organization ID */);

    ResultSet resultSet = stmt.executeQuery();
    resultSet.close();

(Я нашел более полезным вызывать executeQuery() в PreparedStatement, чем execute(). У меня не было вашего кода sproc, поэтому я заставил Organization_Insert вызвать ошибку, сообщение которой содержало количество строк в табличной переменной. Для получения этого было необходимо использовать executeQuery() сообщение об ошибке, выданное в SQLException: с execute() исключение не было выдано.)

person Luke Woodward    schedule 16.11.2014