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 的语法的主要内容,如果未能解决你的问题,请参考以下文章