当前位置: 首页 > 知识库问答 >
问题:

从java调用表值参数的存储过程

柳业
2023-03-14

在我的应用程序中,我想执行像SELECT*FROM tbl这样的查询,其中,@list中的col In(@list)可以有变量no of值。我正在使用MS SQL server数据库。当我搜索这个问题时,我找到了这个链接

http://www.sommarskog.se/arrays-in-sql-2008.html

此链接表示使用表值参数。因此,我使用Microsoft SQL Server Management Studio创建了用户定义的数据类型。

创建类型integer_list_tbltype AS TABLE(n int NOT NULL主键)

然后我写了存储过程

CREATE PROCEDURE get_product_names @prodids integer_list_tbltype READONLY AS
   SELECT p.ProductID, p.ProductName
   FROM   Northwind.dbo.Products p
   WHERE  p.ProductID IN (SELECT n FROM @prodids)

然后使用管理工作室只有我执行了这个程序

DECLARE @mylist integer_list_tbltype
INSERT @mylist(n) VALUES(9),(12),(27),(37)
EXEC get_product_names @mylist

它给了我正确的输出。但是我想知道如何从java源代码中调用这个存储过程。我知道如何用常量参数调用简单的存储过程

CallableStatement proc_stmt = null;
proc_stmt = con.prepareCall("{call test(?)}");
proc_stmt.setString(1,someValue);

但是如何在表值参数情况下调用存储过程呢?

共有3个答案

祁俊喆
2023-03-14

典型的答案(逗号分隔或XML)都与SQL注入有关。我需要一个能让我使用事先准备好的声明的答案。所以我想到了这个:

StringBuilder query = new StringBuilder();
query.append(
  "DECLARE @mylist integer_list_tbltype;" +
  "INSERT @mylist(n) VALUES(?)");
for (int i = 0; i < values.size() - 1; ++i) {
  query.append(",(?) ");
}
query.append("; EXEC get_product_names @mylist ");
PreparedStatement preparedStmt = conn.prepareStatement(query.toString());
for (int i = 0; i < values.size(); ++i) {
    preparedStmt.setObject(i + 1, itemLookupValues.get(i));
}
万俟经纶
2023-03-14

看起来这是JDBC计划中的新增功能,但尚未实施:

http://blogs.msdn.com/b/jdbcteam/archive/2012/04/03/how-would-you-use-table-valued-parameters-tvp.aspx

将参数作为分隔字符串(“9,12,27,37”)传递,然后在SQL Server中创建一个名为“fnSplit”的表值函数,或任何将返回表中整数值的函数(只需搜索“SQL Server split function”,有数百万个)。

禄仲渊
2023-03-14

这在JDBC驱动程序手册中有记录。在你的情况下,你必须这样做:

try (SQLServerCallableStatement stmt =
    (SQLServerCallableStatement) con.prepareCall("{call test(?)}")) {

    SQLServerDataTable table = new SQLServerDataTable();   
    sourceDataTable.addColumnMetadata("n", java.sql.Types.INTEGER);   

    sourceDataTable.addRow(9);
    sourceDataTable.addRow(12);
    sourceDataTable.addRow(27);
    sourceDataTable.addRow(37);

    stmt.setStructured(1, "dbo.integer_list_tbltype", table);  
}

我最近也在一篇文章中记录了这一点。

 类似资料:
  • 我通过Hibernate调用了一个带有OUT参数的存储过程,得到了以下错误: 我的存储过程: Hibernate映射: 我按如下方式调用了存储过程: 有人能解释一下这段代码有什么问题吗?

  • 我在HANA数据库中创建了这个存储过程,它使用两个参数,一个是表类型,另一个是。 现在我想在Java中调用这个过程,我写了这样的东西。 有人能告诉我在调用此存储过程时,如何将对象作为参数中的表实体传递吗?

  • 问题内容: 我正在编写一个简单的Web应用程序以调用存储过程并检索一些数据。它是一个非常简单的应用程序,可以与客户的数据库进行交互。我们传递员工ID和公司ID,存储过程将返回员工详细信息。 Web应用程序无法更新/删除数据,并且正在使用SQL Server。 我正在Jboss AS中部署Web应用程序。我应该使用JPA访问存储过程还是。在这种情况下使用JPA的任何优势。 调用该存储过程的sql语句

  • 我想用java调用一个记录类型表的存储过程。记录只包含数字,但我必须传递整数和小数。 我还没有为我的问题找到合适的解决方案(无论是OracleCallableStatement还是StoredProcedurey)。

  • 我在Oracle中有一个存储过程,如下所示。 我正在从Java调用该过程。我的密码是, 即使我正在获取记录,值也是空的。这意味着如果输出为2行,则while条件执行并打印为空。在SQL Developer中,它工作得很好。提前道谢。

  • 问题内容: 我有一个具有以下属性的类: 现在,我有一个包含这样的对象的对象, 我需要将此数组列表传递给sql服务器存储过程,并将学生对象数据插入表中。如何在Java中最好地实现这一目标?我需要有一个存储过程。 Java版本8,Sql Server 2014(如果有任何用途)。 问题答案: 使用Mark Rotteveel提供的输入,我能够做到。谢谢马克,肖恩也感谢您的输入。这是可能对您有用的任何人