0

我有以下带有用户定义变量的 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 驱动连接数据库)

我一整天都在谷歌上搜索并尝试了许多实现,但没有任何回报。

请有人对此有所了解...

4

1 回答 1

1

(我将假设您已声明Locationtype为表变量。ReadOnly存储过程的参数上的使用暗示了这一点。)

根据 SQL Server 论坛上的这篇文章,Microsoft SQL Server JDBC 驱动程序当前不支持表变量。因此,您似乎必须构建一个 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()。我没有您的存储过程代码,所以我提出Organization_Insert了一个错误,其消息包含表变量中的行数。使用executeQuery()是获取此错误消息所必需的一个 SQLException:execute()没有抛出异常。)

于 2014-11-16T12:46:12.590 回答