国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

詳解Java的JDBC API的存儲(chǔ)過程與SQL轉(zhuǎn)義語法的使用

2019-11-26 14:42:50
字體:
供稿:網(wǎng)友

正如一個(gè)Connection對(duì)象創(chuàng)建Statement和PreparedStatement對(duì)象,它也創(chuàng)造了CallableStatement對(duì)象這將被用來執(zhí)行調(diào)用數(shù)據(jù)庫(kù)存儲(chǔ)過程。

創(chuàng)建CallableStatement對(duì)象:
假設(shè),需要執(zhí)行以下Oracle存儲(chǔ)過程:

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

注意: 上面已經(jīng)寫過Oracle存儲(chǔ)過程,但我們正在使用MySQL數(shù)據(jù)庫(kù),寫相同的存儲(chǔ)過程對(duì)于MySQL如下,以EMP數(shù)據(jù)庫(kù)中創(chuàng)建它:

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 ;

三種類型的參數(shù)有:IN,OUT和INOUT。PreparedStatement對(duì)象只使用IN參數(shù)。 CallableStatement對(duì)象可以使用所有的三個(gè)。

這里是每個(gè)定義:

  • IN:它的值是在創(chuàng)建SQL語句時(shí)未知的參數(shù)。將值綁定到setXXX()方法的參數(shù)。
  • OUT:其值是由它返回的SQL語句提供的參數(shù)。你從OUT參數(shù)的getXXX()方法檢索值。
  • INOUT:同時(shí)提供輸入和輸出值的參數(shù)。綁定setXXX()方法的變量,并與getXXX()方法檢索值。

下面的代碼片段顯示了如何使用該Connection.prepareCall()方法實(shí)例化基于上述存儲(chǔ)過程CallableStatement對(duì)象:

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

String變量的SQL表示存儲(chǔ)過程,使用參數(shù)占位符。

使用CallableStatement對(duì)象是使用PreparedStatement對(duì)象。必須將值綁定到所有的參數(shù)執(zhí)行該語句之前,否則將收到一個(gè)SQLException。

如果有IN參數(shù),只要按照適用于PreparedStatement對(duì)象相同的規(guī)則和技巧;使用對(duì)應(yīng)于要綁定Java數(shù)據(jù)類型的setXXX()方法。

當(dāng)使用OUT和INOUT參數(shù)就必須采用額外CallableStatement方法的registerOutParameter()。registerOutParameter()方法JDBC數(shù)據(jù)類型綁定到數(shù)據(jù)類型的存儲(chǔ)過程返回。

一旦調(diào)用存儲(chǔ)過程,用getXXX()方法的輸出參數(shù)檢索值。這種方法投射SQL類型的值檢索到Java數(shù)據(jù)類型。

關(guān)閉CallableStatement 對(duì)象:
正如關(guān)閉其他Statement對(duì)象,出于同樣的原因,也應(yīng)該關(guān)閉CallableStatement對(duì)象。

close()方法簡(jiǎn)單的調(diào)用將完成這項(xiàng)工作。如果關(guān)閉了Connection對(duì)象首先它會(huì)關(guān)閉CallableStatement對(duì)象為好。然而,應(yīng)該始終明確關(guān)閉的CallableStatement對(duì)象,以確保正確的清除。

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

PS:CallableStatement對(duì)象實(shí)例
下面是利用CallableStatement連同下列g(shù)etEmpName()的MySQL存儲(chǔ)過程的例子:

請(qǐng)確定已經(jīng)在EMP數(shù)據(jù)庫(kù)中創(chuàng)建該存儲(chǔ)過程。可以使用MySQL查詢?yōu)g覽器來完成它。

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 ;

基于對(duì)環(huán)境和數(shù)據(jù)庫(kù)安裝在前面的章節(jié)中進(jìn)行,這個(gè)范例程式碼已被寫入。

復(fù)制下面的例子中JDBCExample.java,編譯并運(yùn)行,如下所示:

//STEP 1. Import required packagesimport 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

現(xiàn)在編譯上面的例子如下:

C:>javac JDBCExample.java

當(dāng)運(yùn)行JDBCExample,它會(huì)產(chǎn)生以下結(jié)果:

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

JDBC的SQL轉(zhuǎn)義語法:
轉(zhuǎn)義語法使能夠使用通過使用標(biāo)準(zhǔn)的JDBC方法和屬性,無法使用數(shù)據(jù)庫(kù)的某些特性的靈活性。

一般的SQL轉(zhuǎn)義語法格式如下:

{keyword 'parameters'}

這里有以下這些,會(huì)發(fā)現(xiàn)非常有用的,而這樣做的JDBC編程的轉(zhuǎn)義序列:

d, t, ts 關(guān)鍵字:
他們幫助確定日期,時(shí)間和時(shí)間戳記文字。如所知,沒有兩個(gè)數(shù)據(jù)庫(kù)管理系統(tǒng)是基于時(shí)間和日期的方式相同。此轉(zhuǎn)義語法告訴驅(qū)動(dòng)程序呈現(xiàn)在目標(biāo)數(shù)據(jù)庫(kù)的格式,日期或時(shí)間。實(shí)現(xiàn)例子:

{d 'yyyy-mm-dd'}

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

下面是一個(gè)簡(jiǎn)單的例子說明如何插入日期表:

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

同樣,可以使用以下兩種語法之一,無論是 t 或 ts:

{t 'hh:mm:ss'}

其中hh=小時(shí),mm=分,ss=秒。使用此語法 {t '13:30:29'}是下午1點(diǎn)三十分29秒.

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

這是上述兩種語法 'd' 和  't' 來表示時(shí)間戳結(jié)合語法。

escape 關(guān)鍵字:
該關(guān)鍵字標(biāo)識(shí)LIKE子句中使用的轉(zhuǎn)義字符。有用使用SQL通配符%,其中匹配零個(gè)或多個(gè)字符時(shí)。例如:

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

如果使用反斜杠字符()作為轉(zhuǎn)義字符,還必須使用兩個(gè)反斜杠字符在Java字符串字面,因?yàn)榉葱备芤彩且粋€(gè)Java轉(zhuǎn)義字符。

fn 關(guān)鍵字:
此關(guān)鍵字代表在DBMS中使用標(biāo)量函數(shù)。例如,可以使用SQL length函數(shù)計(jì)算GE字符串的長(zhǎng)度:

{fn length('Hello World')}

這將返回11,字符串 'Hello World'的長(zhǎng)度。.

call 關(guān)鍵字:
此關(guān)鍵字是用來調(diào)用存儲(chǔ)過程。例如,對(duì)于一個(gè)存儲(chǔ)過程,需要一個(gè)IN參數(shù),請(qǐng)使用以下語法:

{call my_procedure(?)};

對(duì)于一個(gè)存儲(chǔ)過程,需要一個(gè)IN參數(shù)并返回一個(gè)OUT參數(shù),使用下面的語法:

{? = call my_procedure(?)};

oj 關(guān)鍵字:
此關(guān)鍵字用來表示外部聯(lián)接。其語法如下:

{oj outer-join}

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

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

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 紫阳县| 桐城市| 桂林市| 白银市| 萨嘎县| 望江县| 榕江县| 专栏| 武平县| 双牌县| 东方市| 洛川县| 神木县| 龙南县| 涟水县| 博野县| 交口县| 镇原县| 德江县| 驻马店市| 东台市| 隆安县| 张家界市| 兴业县| 布拖县| 深泽县| 京山县| 广元市| 剑河县| 随州市| 寿宁县| 吉林省| 兴城市| 新巴尔虎右旗| 静海县| 邻水| 理塘县| 石泉县| 邻水| 南城县| 汾西县|