oracle實戰第三天--事務處理與函數


第三天

內容介紹

  1. java程序如何操作oracle
  2. 如何在oracle中操作數據
  3. Oracle事務處理
  4. Sql函數的使用

 

期望目標:

  1. 掌握oracle表對數據操作技巧。
  2. 掌握在java程序中操作oracle。
  3. 理解oracle事務概念。
  4. 掌握oracle各種sql函數。

 

Java連接oracle

前面我們一直在pl/sql中操作oracle,那么如何在java程序中操作數據庫呢?

下面我們舉例說明:分頁顯示emp表的用戶信息

Testoracle.jsp

<%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>  

    <title>oracle分頁案例</title>

    <meta http-equiv="pragma" content="no-cache">

    <meta http-equiv="cache-control" content="no-cache">

  </head>

  <body>

    <h2>oracle分頁案例</h2>

    <table>

    <tr>

        <td>雇員名</td>

        <td>薪水</td>

    </tr>

    <%

    //查詢總頁數

    int pageCount = 0;

    //總共有幾條記錄

    int rowCount = 0;

    //每頁顯示幾條記錄

    int pageSize = 3;

    //接收當前的頁數

    String strPageNow = request.getParameter("pageNow");

    int pageNow = 1;

    if(strPageNow!=null)

    {

        pageNow = Integer.valueOf(strPageNow);

    }

   

    Connection conn = null;

       Statement stmt = null;

       try

       {

           //加載驅動

           Class.forName("oracle.jdbc.driver.OracleDriver");

           //得到連接

           conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "tiger");

           stmt = conn.createStatement();

          

           ResultSet rs= stmt.executeQuery("select count(*) from emp");

          

           while(rs.next())

           {

              rowCount = rs.getInt(1);

              if(rowCount%pageSize == 0)

              {

                  pageCount = rowCount/pageSize;

              }

              else

              {

                  pageCount = rowCount/pageSize + 1;

              }

           }

          

           rs = stmt.executeQuery("select * from (select t.*,rownum rn from (select * from emp) t where rownum <=" + pageNow*pageSize + ") where rn >="+((pageNow-1)*pageSize + 1)+"");

 

           while (rs.next())

           {

              out.print("<tr>");

              out.print("<td>"+rs.getString(2)+"</td>");

              out.print("<td>"+rs.getInt(6)+"</td>");

              out.print("</tr>");

           }

          

           out.print("<tr>");

           for(int i =1 ; i<=pageCount; i++ )

           {

              out.print("<a href='testoracle.jsp?pageNow="+i+"'>["+i+"]</a>");

           }

           out.print("</tr>");

       }

       catch (Exception e)

       {

           throw new RuntimeException(e);

       }

       finally

       {

           try

           {

              if (stmt != null)

              {

                  stmt.close();

              }

              if (conn != null)

              {

                  conn.close();

              }

           }

           catch (Exception ex)

           {

              throw new RuntimeException(ex);

           }

       }

    %>

    </table>

  </body>

</html>

 

 

 

在oracle中操作數據

 

使用特定格式插入日期值--使用to_date()函數

請思考:如何插入列帶有日期的表,並按照年-月-日的格式插入?

insert into emp
values
(7950,'ZHANGSAN','MANAGER','7782',
to_date('1988-11-11','yyyy-mm-dd'),
1200.00,50.00,10);

insert into emp
values
(7951,'ZHANGSAN','MANAGER','7782',
to_date('1988/11/11','yyyy/mm/dd'),
1200.00,50.00,10);

 

 

使用子查詢插入數據

當使用values子句時,一次只能插入一行數據,當使用子查詢插入數據時,一條insert語句可以插入大量的數據,當處理行遷移或者裝載外部表的數據到數據庫時,可以使用子查詢來插入數據。

create table myemp
(
    myId number(4),
    myName varchar2(50),
    myDept number(5)
);

insert into myemp(myId,myname,mydept)
select empno,ename,deptno from emp
where deptno = 10;

select * from myemp;

 

 

使用子查詢更新數據

使用update語句更新數據時,既可以使用表達式或者數值直接修改數據,也可以使用子查詢修改數據。

如:希望員工scott的崗位、工資、補助與smith員工一樣

update emp set (job,sal,comm)
= (select job,sal,comm from emp where ename='SMITH')
where ename = 'SCOTT';

 

 

Oracle中事務處理

事務用於保證數據的一致性,它由一組相關的dml語句組成,該組的dml語句要么全部成功,要么全部失敗。

如:網上轉帳就是典型的要用事務處理,用以保證數據的一致性。

 

事務和鎖

當執行事務操作時(dml語句),oracle會在被作用的表上加鎖,防止其它用戶改表的結構,這里對我們用戶來講是非常重要的。

 

提交事務

當執行commit語句可以提交事務,當執行了commit語句后,會確認事務的變化、結束事務、刪除保存點、釋放鎖,當使用commit語句結束事務后,其它會話將可以查看到事務變化后的新數據。

 

回退事務

在介紹回退事務前,我們先介紹一下保存點(savepoint)的概念和作用,保存點是事務中的一點,用於取消部分事務,當結束事務時,會自動的刪除該事務所定義的所有保存點。當執行rollback時,通過指定保存點可以回退指定的點。

savepoint a1;

delete from emp where empno = 7900;

savepoint a2;

delete from emp where empno = 7788;

rollback to a2;

rollback to a1;

 

事務的幾個重要操作

a.設置保存點

svepoint a;

b.取消部分事務

Rollback to a;

c.取消全部事務

Rollback;

 

在java程序中如何使用事務

在java操作數據庫時,為了保證數據的一致性,比如轉帳操作

1)  在一個帳戶減掉10元

2)  在另一個帳戶加上10元

我們看看如何使用事務?

package com.anllin.jdbc.oracle;

 

import java.sql.*;

 

public class TestTransation

{

    public static void main(String[] args)

    {

       Connection conn = null;

       Statement stmt = null;

 

       try

       {

           Class.forName("oracle.jdbc.driver.OracleDriver");

           conn = DriverManager.getConnection(

                  "jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "tiger");

           //加入事務處理

           conn.setAutoCommit(false);

 

           stmt = conn.createStatement();

           stmt.executeUpdate("update emp set sal=sal-100 where ename='SCOTT'");

          

           //制造異常

           int i = 7/0;

          

           stmt.executeUpdate("update emp set sal=sal+100 where ename='SMITH'");

           //提交事務

           conn.commit();

       }

       catch (Exception e)

       {

           try

           {

              //回滾事務

              conn.rollback();

           }

           catch (SQLException e1)

           {

              throw new RuntimeException(e1);

           }

           throw new RuntimeException(e);

       }

       finally

       {

           if(stmt != null)

           {

              try

              {

                  stmt.close();

              }

              catch (SQLException e)

              {

                  throw new RuntimeException(e);

              }

           }

           if(conn != null)

           {

              try

              {

                  conn.close();

              }

              catch (SQLException e)

              {

                  throw new RuntimeException(e);

              }

           }

       }

    }

}

 

 

 

只讀事務

只讀事務是指只允許執行查詢的操作,而不允許執行其它dml操作的事務,使用只讀事務可以確保用戶只能取得某時間點的數據,

假定機票代售點每天18點開始統計今天的銷售情況,這時可以使用只讀事務,在設置了只讀事務后,盡管其它會話可能會提交新的事務,但是只讀事務將不會取得最新數據的變化,從而可以保證取得特定時間點的數據信息。

 

設置只讀事務

set transaction read only;

 

用system用戶登錄,然后執行以下操作:

set transaction read only;

 

再另外起一個客戶端,用scott用戶登錄,執行以下操作:

insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
values(8000,'LISI','CLERK',7902,to_date('1983-05-16','yyyy-mm-dd'),1200.00,50.00,10);

 

select * from emp;--可以看到新增的數據

 

此時,再用system用戶操作

select * from scott.emp; --將看不到新增的數據

 

 

Sql函數的使用

字符函數

介紹:

字符函數是oralce中最常用的函數,我們來看看有哪些字符函數:

Lower(char): 將字符串轉化為小寫的格式

Upper(char): 將字符串轉化為大寫的格式

Length(char): 返回字符串的長度

Substr(char,m,n): 取字符串的子串,m表示截取起始位置,n表示截取的長度

將所有員工的名字按小寫的方式顯示

select lower(ename),sal,job from emp;

將所有員工的名字按大寫的方式顯示

select upper(ename),sal,job from emp;

顯示正好為5個字符的員工的姓名

select * from emp where length(ename) = 5;

顯示所有員工姓名的前三個字符。

select substr(ename,1,3) from emp;

以首字母大寫的方式顯示所有員工的姓名

select upper(substr(ename,1,1))
||
lower(substr(ename,2,length(ename)-1))
from emp;

以首字母小寫的方式顯示所有員工的姓名。

select lower(substr(ename,1,1))
||
upper(substr(ename,2,length(ename)-1))
from emp;

 

Replace(char1,search_string,replace_string):將字符中某段字符串替換成所需的字符串

Instr(char1,char2,[n[,m]])取子串在字符串的位置

顯示所有員工的姓名,用a替換所有”A”

select replace(ename,'A','a') from emp;

 

 

數學函數

介紹:

數學函數的輸入參數和返回值的數據類型都是數字類型的,數學函數包括

Abs(n) 返回數字n的絕對值。

Cos(n) 返回數字的余弦值。

Cosh(n) 返回數字的雙曲余弦值

exp(n) 返回數字e的n次冪

power(m,n) 返回m的n次冪

ln(n)  返回e為底的n的對數

log(m,n)  返回m為底的n的對數

sin(n) 返回數字的正弦值

sinh(n) 返回數字的雙曲正弦值

sqrt(n) 返回數字的平方根

tan(n) 返回數字的正切值

tanh(n) 返回數字的雙曲正切值

acos(n) 返回數字的反余弦值

asin(n) 返回數字的反正弦值

atan(n) 返回數字的反正切值

我們最常用的有:

Round(n,[m])該函數用於執行四舍五入。如果省掉m,則四舍五入到整數;如果m是正數,則四舍五入到小數點的m位后;如果m是負數,則四舍五入到小數點的m位前。

Trunk(n,[m])該函數用於截取數字。如果省掉m,就截去小數部分,如果m是正數,就截取到小數點的m位后,如果m是負數,則截取到小數點的前m位。

Mod(m,n)取模

Floor(n)返回小於或等於n的最大整數

Ceil(n)返回大於或等於n的最小整數

對數字的處理,在財務系統或銀行系統中用的最多,不同的處理方法,對財務報表有不同的結果。

案例:

顯示在一個月為30天的情況所有員工的薪金,忽略余數。

select trunc(sal/30),ename from emp;

output:

TRUNC(SAL/30) ENAME

------------- ----------

           40 LISI

           43 zhangsan

           51 wangwu

           49 zhaoliu

           30 SMITH

           53 ALLEN

           41 WARD

           99 JONES

           41 MARTIN

           95 BLAKE

           81 CLARK

           20 SCOTT

          166 KING

           50 TURNER

           36 ADAMS

           31 JAMES

          100 FORD

           43 MILLER

 

示例:

insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
values(8001,'zhangsan','CLERK',7902,to_date('1983-06-18','yyyy-mm-dd'),1300.34,50.52,10);
insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
values(8002,'wangwu','CLERK',7902,to_date('1983-09-22','yyyy-mm-dd'),1530.69,50.14,10);
insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
values(8003,'zhaoliu','CLERK',7902,to_date('1983-10-20','yyyy-mm-dd'),1480.52,50.73,10);

select round(sal),sal from emp

Output:

ROUND(SAL)       SAL

---------- ---------

      1200   1200.00

      1300   1300.34

      1531   1530.69

      1481   1480.52

 

select round(sal,1),sal from emp;

output:

ROUND(SAL,1)       SAL

------------ ---------

        1200   1200.00

      1300.3   1300.34

      1530.7   1530.69

      1480.5   1480.52

 

select trunc(sal),sal from emp;

output:

TRUNC(SAL)       SAL

---------- ---------

      1200   1200.00

      1300   1300.34

      1530   1530.69

      1480   1480.52

 

select trunc(sal,1),sal from emp;

output:

TRUNC(SAL,1)       SAL

------------ ---------

        1200   1200.00

      1300.3   1300.34

      1530.6   1530.69

      1480.5   1480.52

 

select floor(sal),sal from emp;

output:

FLOOR(SAL)       SAL

---------- ---------

      1200   1200.00

      1300   1300.34

      1530   1530.69

      1480   1480.52

 

select ceil(sal),sal from emp;

output:

CEIL(SAL)       SAL

---------- ---------

      1200   1200.00

      1301   1300.34

      1531   1530.69

      1481   1480.52

 

select mod(10,3) from dual;

output:

MOD(10,3)

----------

         1

 

 

日期函數

介紹:

日期函數用於處理date類型的數據。

默認情況下日期格式是dd-mon-yy 即12-7月-78

1)sysdate該函數返回系統時間

2)add_months(d,n)給指定日期增加n 個月份

3)last_day(d)返回指定日期所在月分的最后一天

查找已經入職8個月多的員工

select * from emp where sysdate > add_months(hiredate,8);

顯示滿10年服務年限的員工的姓名和受雇日期。

select * from emp where sysdate >= add_months(hiredate,12*10);

對於每個員工,顯示其加入公司的天數。

select trunc(sysdate-hiredate) days,ename from emp;

找出各月倒數第3天受雇的所有員工。

select hiredate,last_day(hiredate),ename from emp
where last_day(hiredate)-2 = hiredate;

 

 

轉換函數

轉換函數用於將數據類型從一種轉為另外一種,在某些情況下,oracle server 允許值的數據類型和實際的不一樣,這時oracle server會隱含的轉化數據。

比如:

create table t1(id int);
insert into t1 values('10');--這里oracle會自動將'10'->10

create table t2(id varchar2(10));
insert into t2 values(1);-- 這里oracle會自動將1->'1'

我們要說的盡管oracle可以進行隱含的數據類型的轉換,但是它並不適應所有的情況,為了提高程序的可靠性,我們應該使用轉換函數。

 

To_char()

你可以使用

select ename,hiredate,sal from emp where deptno=10;

顯示信息,可是,在某些情況下,這個並不能滿足你的需求.

 

格式

描述

示例

yy

兩位數字的年份

2004à04

yyyy

四位數字的年份

2004年à2004

mm

兩位數字的月份

8月à08

dd

2位數字的天

30號à30

hh24

小時用24小時制

8點à20

hh12

小時用12小時制

8點à08

mi

分鍾

15

ss

50

 

格式

描述

9

顯示數字,並忽略前面0

0

顯示數字,如位數不足,則用0補齊

.

在指定位置顯示小數點

,

在指定位置顯示逗號

$

在數字前加美元符

L

在數字前加本地貨幣符號

C

在數字前加國際貨幣符號

G

在指定位置顯示組分隔符、

D

在指定位置顯示小數點符號.

 

如:日期是否可以顯示時、分、秒

insert into emp
values(8004,'Test','MANAGER',7782,sysdate,1360.52,100,20);

select ename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss')
from emp;

Output:

Test       2012-02-09 20:09:45

 

薪水是否可以顯示指定的貨幣符號。

select ename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss'),
to_char(sal,'L99999.99')
from emp;
output:

ENAME      TO_CHAR(HIREDATE,'YYYY-MM-DDHH TO_CHAR(SAL,'L99999.99')

---------- ------------------------------ ------------------------

Test       2012-02-09 20:09:45                     ¥1360.52

LISI       1983-05-16 00:00:00                     ¥1200.00


select ename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss'),
to_char(sal,'L99,999.99')
from emp;

output:

ENAME      TO_CHAR(HIREDATE,'YYYY-MM-DDHH TO_CHAR(SAL,'L99,999.99')

---------- ------------------------------ -------------------------

Test       2012-02-09 20:09:45                     ¥1,360.52

LISI       1983-05-16 00:00:00                     ¥1,200.00

 

顯示1980年入職的所有員工

select * from emp where to_char(hiredate,'yyyy') = 1980;

output:

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

----- ---------- --------- ----- ----------- --------- --------- ------

 7369 SMITH      CLERK      7902 1980-12-17     900.00               20

顯示所有12月份入職的員工

select * from emp where to_char(hiredate,'mm') = 12;

output:

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

----- ---------- --------- ----- ----------- --------- --------- ------

 7369 SMITH      CLERK      7902 1980-12-17     900.00               20

 7900 JAMES      CLERK      7698 1981-12-03     950.00               30

 7902 FORD       ANALYST    7566 1981-12-03    3000.00               20

 

To_date()

用於將字符串轉換成date類型的數據。

能否按照中國人習慣的方式年-月-日添加日期。

insert into emp
values(8005,'ChenWen','ANALYST',7566,to_date('1986-9-22','yyyy-mm-dd'),1850.52,100,20);

 

 

系統函數

1)terminal: 當前會話客戶所對應的終端的標識符。

2)language: 語言。

3)db_name: 當前數據庫名稱。

4)nls_date_format: 當前會話客戶所對應的日期格式。

5) session_user: 當前會話客戶所對應的數據庫用戶名。

6)current_schema: 當前會話客戶所對應的默認方案名。

7)host: 返回數據庫所在主機的名稱。

通過該函數,可以查詢一些重要信息,

比如你正在使用哪個數據庫?

select sys_context('userenv','db_name') as dbname from dual;

output:

DBNAME

--------------------------------------------------------------------------------

Orcl

 

select
sys_context('userenv','terminal') as dbterminal,
sys_context('userenv','language') as dblanguage,
sys_context('userenv','session_user') as sessionuser,
sys_context('userenv','current_schema') as currentschema,
sys_context('userenv','host') as dbhost,
sys_context('userenv','nls_date_format') as dateformat,
sys_context('userenv','db_name') as dbname
from dual;

output:

DBTERMINAL                                                             DBLANGUAGE                                                                       SESSIONUSER                                                                      CURRENTSCHEMA                                                                    DBHOST                                                                           DATEFORMAT                                                                       DBNAME

--------------------------------------------------------------

2011-20030430JR                                                                  SIMPLIFIED-CHINESE_CHINA.AL32UTF8                                                SCOTT                                                                           SCOTT                                                                            WORKGROUP\2011-20030430JR                                                        DD-MON-RR                                                                        orcl

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM