热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详解Java的JDBCAPI的存储过程与SQL转义语法的使用

这篇文章主要介绍了详解Java的JDBCAPI的存储过程与SQL转义语法的使用,JDBC是Java用于连接使用各种数据库的API,需要的朋友可以参考下

正如一个Connection对象创建Statement和PreparedStatement对象,它也创造了CallableStatement对象这将被用来执行调用数据库存储过程。

创建CallableStatement对象:
假设,需要执行以下Oracle存储过程:

CREATE OR REPLACE PROCEDURE getEmpName 
  (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
  SELECT first INTO EMP_FIRST
  FROM Employees
  WHERE ID = EMP_ID;
END;

注意: 上面已经写过Oracle存储过程,但我们正在使用MySQL数据库,写相同的存储过程对于MySQL如下,以EMP数据库中创建它:

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
  (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
  SELECT first INTO EMP_FIRST
  FROM Employees
  WHERE ID = EMP_ID;
END $$

DELIMITER ;

三种类型的参数有:IN,OUT和INOUT。PreparedStatement对象只使用IN参数。 CallableStatement对象可以使用所有的三个。

这里是每个定义:

  • IN:它的值是在创建SQL语句时未知的参数。将值绑定到setXXX()方法的参数。
  • OUT:其值是由它返回的SQL语句提供的参数。你从OUT参数的getXXX()方法检索值。
  • INOUT:同时提供输入和输出值的参数。绑定setXXX()方法的变量,并与getXXX()方法检索值。

下面的代码片段显示了如何使用该Connection.prepareCall()方法实例化基于上述存储过程CallableStatement对象:

CallableStatement cstmt = null;
try {
  String SQL = "{call getEmpName (?, ?)}";
  cstmt = conn.prepareCall (SQL);
  . . .
}
catch (SQLException e) {
  . . .
}
finally {
  . . .
}

String变量的SQL表示存储过程,使用参数占位符。

使用CallableStatement对象是使用PreparedStatement对象。必须将值绑定到所有的参数执行该语句之前,否则将收到一个SQLException。

如果有IN参数,只要按照适用于PreparedStatement对象相同的规则和技巧;使用对应于要绑定Java数据类型的setXXX()方法。

当使用OUT和INOUT参数就必须采用额外CallableStatement方法的registerOutParameter()。registerOutParameter()方法JDBC数据类型绑定到数据类型的存储过程返回。

一旦调用存储过程,用getXXX()方法的输出参数检索值。这种方法投射SQL类型的值检索到Java数据类型。

关闭CallableStatement 对象:
正如关闭其他Statement对象,出于同样的原因,也应该关闭CallableStatement对象。

close()方法简单的调用将完成这项工作。如果关闭了Connection对象首先它会关闭CallableStatement对象为好。然而,应该始终明确关闭的CallableStatement对象,以确保正确的清除。

CallableStatement cstmt = null;
try {
  String SQL = "{call getEmpName (?, ?)}";
  cstmt = conn.prepareCall (SQL);
  . . .
}
catch (SQLException e) {
  . . .
}
finally {
  cstmt.close();
}

PS:CallableStatement对象实例
下面是利用CallableStatement连同下列getEmpName()的MySQL存储过程的例子:

请确定已经在EMP数据库中创建该存储过程。可以使用MySQL查询浏览器来完成它。

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
  (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
  SELECT first INTO EMP_FIRST
  FROM Employees
  WHERE ID = EMP_ID;
END $$

DELIMITER ;

基于对环境和数据库安装在前面的章节中进行,这个范例程式码已被写入。

复制下面的例子中JDBCExample.java,编译并运行,如下所示:

//STEP 1. Import required packages
import java.sql.*;

public class JDBCExample {
  // JDBC driver name and database URL
  static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; 
  static final String DB_URL = "jdbc:mysql://localhost/EMP";

  // Database credentials
  static final String USER = "username";
  static final String PASS = "password";
  
  public static void main(String[] args) {
  Connection cOnn= null;
  CallableStatement stmt = null;
  try{
   //STEP 2: Register JDBC driver
   Class.forName("com.mysql.jdbc.Driver");

   //STEP 3: Open a connection
   System.out.println("Connecting to database...");
   cOnn= DriverManager.getConnection(DB_URL,USER,PASS);

   //STEP 4: Execute a query
   System.out.println("Creating statement...");
   String sql = "{call getEmpName (?, ?)}";
   stmt = conn.prepareCall(sql);
   
   //Bind IN parameter first, then bind OUT parameter
   int empID = 102;
   stmt.setInt(1, empID); // This would set ID as 102
   // Because second parameter is OUT so register it
   stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
   
   //Use execute method to run stored procedure.
   System.out.println("Executing stored procedure..." );
   stmt.execute();

   //Retrieve employee name with getXXX method
   String empName = stmt.getString(2);
   System.out.println("Emp Name with ID:" + 
        empID + " is " + empName);
   stmt.close();
   conn.close();
  }catch(SQLException se){
   //Handle errors for JDBC
   se.printStackTrace();
  }catch(Exception e){
   //Handle errors for Class.forName
   e.printStackTrace();
  }finally{
   //finally block used to close resources
   try{
     if(stmt!=null)
      stmt.close();
   }catch(SQLException se2){
   }// nothing we can do
   try{
     if(conn!=null)
      conn.close();
   }catch(SQLException se){
     se.printStackTrace();
   }//end finally try
  }//end try
  System.out.println("Goodbye!");
}//end main
}//end JDBCExample

现在编译上面的例子如下:

C:>javac JDBCExample.java

当运行JDBCExample,它会产生以下结果:

C:>java JDBCExample
Connecting to database...
Creating statement...
Executing stored procedure...
Emp Name with ID:102 is Zaid
Goodbye!

JDBC的SQL转义语法:
转义语法使能够使用通过使用标准的JDBC方法和属性,无法使用数据库的某些特性的灵活性。

一般的SQL转义语法格式如下:

{keyword 'parameters'}

这里有以下这些,会发现非常有用的,而这样做的JDBC编程的转义序列:

d, t, ts 关键字:
他们帮助确定日期,时间和时间戳记文字。如所知,没有两个数据库管理系统是基于时间和日期的方式相同。此转义语法告诉驱动程序呈现在目标数据库的格式,日期或时间。实现例子:

{d 'yyyy-mm-dd'}

其中yyyy=年,mm =月,DD =日。使用这种语法 {d '2009-09-03'}是2009年3月9日。

下面是一个简单的例子说明如何插入日期表:

//Create a Statement object
stmt = conn.createStatement();
//Insert data ==> ID, First Name, Last Name, DOB
String sql="INSERT INTO STUDENTS VALUES" +
       "(100,'Zara','Ali', {d '2001-12-16'})";

stmt.executeUpdate(sql);

同样,可以使用以下两种语法之一,无论是 t 或 ts:

{t 'hh:mm:ss'}

其中hh=小时,mm=分,ss=秒。使用此语法 {t '13:30:29'}是下午1点三十分29秒.

{ts 'yyyy-mm-dd hh:mm:ss'}

这是上述两种语法 'd' 和  't' 来表示时间戳结合语法。

escape 关键字:
该关键字标识LIKE子句中使用的转义字符。有用使用SQL通配符%,其中匹配零个或多个字符时。例如:

String sql = "SELECT symbol FROM MathSymbols
       WHERE symbol LIKE '\%' {escape ''}";
stmt.execute(sql);

如果使用反斜杠字符()作为转义字符,还必须使用两个反斜杠字符在Java字符串字面,因为反斜杠也是一个Java转义字符。

fn 关键字:
此关键字代表在DBMS中使用标量函数。例如,可以使用SQL length函数计算GE字符串的长度:

{fn length('Hello World')}

这将返回11,字符串 'Hello World'的长度。.

call 关键字:
此关键字是用来调用存储过程。例如,对于一个存储过程,需要一个IN参数,请使用以下语法:

{call my_procedure(?)};

对于一个存储过程,需要一个IN参数并返回一个OUT参数,使用下面的语法:

{? = call my_procedure(?)};

oj 关键字:
此关键字用来表示外部联接。其语法如下:

{oj outer-join}

外连接表={LEFT| RIGHT| FULL}外连接{表|外连接}的搜索条件。例如:

String sql = "SELECT Employees 
       FROM {oj ThisTable RIGHT
       OUTER JOIN ThatTable on id = '100'}";
stmt.execute(sql);


推荐阅读
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
author-avatar
无视一个水阿哥_470
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有