JDBC 连接 prepareCall SQL 的语法

Posted

技术标签:

【中文标题】JDBC 连接 prepareCall SQL 的语法【英文标题】:Syntax of JDBC Connection prepareCall SQL 【发布时间】:2015-02-07 12:45:18 【问题描述】:

我正在阅读JavaDocs for Connection#prepareCall

sql - 可能包含一个或多个“?”的 SQL 语句参数占位符。通常,此语句是使用 JDBC 调用转义语法指定的。

根据这个流行的mkyong JDBC tutorial,我看到方法是这样执行的:

String insertStoreProc = "call insertDBUSER(?,?,?,?)";
callableStatement = dbConnection.prepareCall(insertStoreProc);

我想知道:

    为什么将字符串封装在大括号 ( ... ) 中? 为什么call 继续过程的名称?

最重要的是 call <nameOfProcedure> 是跨所有 JDBC 驱动程序执行所有存储过程的正确语法吗?还是 call ... 特定于特定类型的驱动程序?

此过程调用语法是否有变体?例如,是否存在可能将" execute <nameOfProcedure> " 传递给prepareCall 方法的场景/驱动程序?有这方面的文档吗?


更新:

根据CallableStatement,JDBC 提供了 2 种有效语法,用于跨所有驱动程序以标准方式调用 procs:

?= call <procedure-name>[(<arg1>,<arg2>, ...)]

还有:

call <procedure-name>[(<arg1>,<arg2>, ...)]

但目前还不清楚何时使用其中任何一个(即:何时将call?= 放在一起)。

【问题讨论】:

你应该阅读java.sql.CallableStatement,所有这些问题都在这里得到解答。 感谢@LuiggiMendoza (+1) - 请查看我关于使用?= 的更新和后续问题。再次感谢! 呃...阅读特定数据库引擎的正确 JDBC 驱动程序,其中解释了一个或另一个的用法。 这就是存储过程的工作方式。 SQL 存储过程只能返回单个值RETURN,并且它可以有 OUT 参数。存储过程的返回值不同于它在被调用时可以保持打开的ResultSet(s),但这是特定于数据库引擎的。 JDBC 提供了最通用的方式来访问数据库引擎,但它依赖于数据库引擎和 JDBC 驱动程序实现对所有功能的支持、特定供应商功能或不完整的数据库引擎。 顺便说一下,这些是 cmets,而不是答案。 【参考方案1】:

JDBC specification,第 13.4 节转义语法定义了许多转义,称为 JDBC 转义。这些转义用花括号包裹。调用转义的规范是:

如果数据库支持存储过程,则可以使用 JDBC 转义语法调用它们,如下所示:

call <procedure_name> [(<argument-list>)]

或者,如果一个过程返回一个结果参数:

? = call <procedure_name> [(<argument-list>)]

方括号表示(参数列表)部分是可选的。输入参数可以是文字或参数标记。有关参数的信息,请参见第 108 页的“设置参数”。

这也记录在java.sql.CallableStatement

所以名称 call 和花括号都在 JDBC 规范中指定。

关于你问题的第二部分。 JDBC 是一种尽可能独立于数据库的规范,为此它 - 通常 - 默认为 SQL 标准。 IIRC SQL 规范指定存储过程要么没有返回值,要么只有一个返回值。如果存储过程没有返回值,则使用第一个调用语法。如果存储过程只有一个返回值,则使用第二个。

存储过程也可以有OUT 参数(不要与结果集混淆),它们在普通参数列表中定义。

【讨论】:

感谢@Mark Rotteveel (+1) - 我希望我能多点赞!一个快速的后续问题:似乎 JDBC 显然支持存储过程的三种类型的输出:(1)返回值,(2)输出参数和(3)结果集。 JDBC 规范是否权衡了这些输出的使用地点/时间/方式?换句话说,对于什么构成返回值、输出参数和结果集,是否有 JDBC 标准?再次非常感谢! @IAmYourFaja 这在 JDBC 中并没有真正指定,我相信您需要查看 SQL 规范。但总的来说:返回值:RETURN value语句在SP中返回的单个值,OUT参数在SP中获取一次值(或至少:分配给OUT参数的最后一个值是那个你回来)。结果集就是这样:从存储过程返回的行(如果数据库支持,可以有多个结果集!)。结果集字段应该被定义为参数。 @IAmYourFaja BTW:如果这解决了你的问题,那么请点击复选标记接受答案。

以上是关于JDBC 连接 prepareCall SQL 的语法的主要内容,如果未能解决你的问题,请参考以下文章

JDBC-DAO层数据访问工具类的实现

JDBC调用存储过程,进参出参

使用 addBatch 和 executeBatch 时是不是必须使用相同的 prepareCall?为啥?

通过JDBC API调用存储过程的范例

在prepareCall后遇到符号\"CLOSE\"

如何使用 JDBC 调用存储在数据库中的函数或存储过程