2013年11月11日 星期一

oracle 判斷中英文

SELECT

CASE WHEN  (LENGTH(FAC_NAME_IN) = LENGTHB(FAC_NAME_IN)) THEN FAC_NAME_IN END CUST_ENG_NAME ,

CASE WHEN  (LENGTH(FAC_NAME_IN) != LENGTHB(FAC_NAME_IN)) THEN FAC_NAME_IN END CUST_CHT_NAME 

FROM TABLENAME_IN DTL

oracle 讀取txt檔

Oracle的UTL_FILE用文件的I/O操作。
(1)Oracle10g之前的版本需要指定utl_file包可以操作的目。
         方法: 1、alter system set utl_file_dir='e:/utl' scope=spfile;

 2、在init.ora文件中,配置如下:UTL_FILE=E:/utl或者UTL_FILE_DIR=E:/utl;
 (2)Oracle10g之后的版本,


1.創建目錄:
2 CREATE [OR REPLACE] DIRECTORY directory AS 'pathname';
32.目錄創建以後,就可以把讀寫權限授予特定用戶,具體語法如下:
4 GRANT READ[,WRITE] ON DIRECTORY directory TO username; 

utl_file.fopen(
file_location IN VARCHAR2 --路径
file_name     IN VARCHAR2,   --文件名称
open_mode     IN VARCHAR2,   --打开模式 R  W  A 追加
max_linesize  IN BINARY_INTEGER DEFAULT NULL)
RETURN file_type;

DECLARE
  v_output  utl_file.file_type;
  v_contxt  VARCHAR2(250);
  v_pathna varchar2(10);
BEGIN
  v_pathna := 'utl_file_dir';
  v_output:= utl_file.fopen(v_pathna, 'test.txt', 'R');
  LOOP
    BEGIN
      utl_file.get_line(v_output, v_contxt);
      dbms_output.put_line(v_contxt);
    EXCEPTION
      WHEN OTHERS THEN
        EXIT;
    END;
  END LOOP;
  utl_file.fclose(v_output);
END ;

2013年11月5日 星期二

ORACLE 判斷資料中, 有沒有中文字

SELECT *  FROM table a WHERE LENGTH (id) != LENGTHB (id);
區別:length   是字串長度,lengthb   是位元組長度


select length('abc中國')
  from dual;
 
-- 結果: 5 碼
--------------------------
 
select lengthb('abc中國')
  from dual;
 
-- 結果: 9 碼 (UTF8 一個中文字 3 碼)
--------------------------
 
select 1
  from dual
 where length('abc中國') = lengthb('abc中國');
 
-- 結果: 0 row (表示字串中有中文字)
--------------------------
 
select 1
  from dual
 where length('abc') = lengthb('abc');
 
-- 結果: 1 row (表示字串中無中文字)

2013年10月31日 星期四

ORACLE 找特定字元位置

ORACLE 找特定字元位置 類似 JAVA 的 INDEXOF
 INSTR('ccrbatch.aaa', '.') 回傳 9

 搭配SUBSTR 可以取 . 後面的文字
select subStr('ccrbatch.ABC',INSTR('ccrbatch.ABC', '.')+1) from CTB_CT;
回傳 ABC



2013年10月17日 星期四

PL/SQL 令人煩惱的單引號

"跳脫(escaping)"單引號;可用兩個連續的記號來達成

FUNCTION esc(text IN VARCHRAR2)
   RETURN VARCHAR2
IS
BEGIN
   RETURN '''' || REPLACE(text,'''','''''') || '''' ;
END;

2013年10月14日 星期一

JDBC读取新插入Oracle数据库Sequence值的5种方法

  1. //公共代码:得到数据库连接  
  2. public Connection getConnection() throws Exception{  
  3.     Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();  
  4.     Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:dbname""username""password");  
  5.     return conn;  
  6. }  
  7.   
  8. //方法一  
  9. //先用select seq_t1.nextval as id from dual 取到新的sequence值。  
  10. //然后将最新的值通过变量传递给插入的语句:insert into t1(id) values(?)   
  11. //最后返回开始取到的sequence值。  
  12. //这种方法的优点代码简单直观,使用的人也最多,缺点是需要两次sql交互,性能不佳。  
  13. public int insertDataReturnKeyByGetNextVal() throws Exception {  
  14.     Connection conn = getConnection();  
  15.     String vsql = "select seq_t1.nextval as id from dual";  
  16.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);  
  17.     ResultSet rs=pstmt.executeQuery();  
  18.     rs.next();  
  19.     int id=rs.getInt(1);  
  20.     rs.close();  
  21.     pstmt.close();  
  22.     vsql="insert into t1(id) values(?)";  
  23.     pstmt =(PreparedStatement)conn.prepareStatement(vsql);  
  24.     pstmt.setInt(1, id);  
  25.     pstmt.executeUpdate();  
  26.     System.out.print("id:"+id);  
  27.     return id;  
  28. }  
  29.   
  30. //方法二  
  31. //先用insert into t1(id) values(seq_t1.nextval)插入数据。  
  32. //然后使用select seq_t1.currval as id from dual返回刚才插入的记录生成的sequence值。  
  33. //注:seq_t1.currval表示取出当前会话的最后生成的sequence值,由于是用会话隔离,只要保证两个SQL使用同一个Connection即可,对于采用连接池应用需要将两个SQL放在同一个事务内才可保证并发安全。  
  34. //另外如果会话没有生成过sequence值,使用seq_t1.currval语法会报错。  
  35. //这种方法的优点可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码,缺点是需要两次sql交互,性能不佳,并且容易产生并发安全问题。  
  36. public int insertDataReturnKeyByGetCurrVal() throws Exception {  
  37.     Connection conn = getConnection();  
  38.     String vsql = "insert into t1(id) values(seq_t1.nextval)";  
  39.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);  
  40.     pstmt.executeUpdate();  
  41.     pstmt.close();  
  42.     vsql="select seq_t1.currval as id from dual";  
  43.     pstmt =(PreparedStatement)conn.prepareStatement(vsql);  
  44.     ResultSet rs=pstmt.executeQuery();  
  45.     rs.next();  
  46.     int id=rs.getInt(1);  
  47.     rs.close();  
  48.     pstmt.close();  
  49.     System.out.print("id:"+id);  
  50.     return id;  
  51. }  
  52.   
  53. //方法三  
  54. //采用pl/sql的returning into语法,可以用CallableStatement对象设置registerOutParameter取得输出变量的值。  
  55. //这种方法的优点是只要一次sql交互,性能较好,缺点是需要采用pl/sql语法,代码不直观,使用较少。  
  56. public int insertDataReturnKeyByPlsql() throws Exception {  
  57.     Connection conn = getConnection();  
  58.     String vsql = "begin insert into t1(id) values(seq_t1.nextval) returning id into :1;end;";  
  59.     CallableStatement cstmt =(CallableStatement)conn.prepareCall ( vsql);   
  60.     cstmt.registerOutParameter(1, Types.BIGINT);  
  61.     cstmt.execute();  
  62.     int id=cstmt.getInt(1);  
  63.     System.out.print("id:"+id);  
  64.     cstmt.close();  
  65.     return id;  
  66. }  
  67.   
  68. //方法四  
  69. //采用PreparedStatement的getGeneratedKeys方法  
  70. //conn.prepareStatement的第二个参数可以设置GeneratedKeys的字段名列表,变量类型是一个字符串数组  
  71. //注:对Oracle数据库这里不能像其它数据库那样用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,这种语法是用来取自增类型的数据。  
  72. //Oracle没有自增类型,全部采用的是sequence实现,如果传Statement.RETURN_GENERATED_KEYS则返回的是新插入记录的ROWID,并不是我们相要的sequence值。  
  73. //这种方法的优点是性能良好,只要一次sql交互,实际上内部也是将sql转换成oracle的returning into的语法,缺点是只有Oracle10g才支持,使用较少。  
  74. public int insertDataReturnKeyByGeneratedKeys() throws Exception {  
  75.     Connection conn = getConnection();  
  76.     String vsql = "insert into t1(id) values(seq_t1.nextval)";  
  77.     PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql,new String[]{"ID"});  
  78.     pstmt.executeUpdate();  
  79.     ResultSet rs=pstmt.getGeneratedKeys();  
  80.     rs.next();  
  81.     int id=rs.getInt(1);  
  82.     rs.close();  
  83.     pstmt.close();  
  84.     System.out.print("id:"+id);  
  85.     return id;  
  86. }  
  87.   
  88. //方法五  
  89. //和方法三类似,采用oracle特有的returning into语法,设置输出参数,但是不同的地方是采用OraclePreparedStatement对象,因为jdbc规范里标准的PreparedStatement对象是不能设置输出类型参数。  
  90. //最后用getReturnResultSet取到新插入的sequence值,  
  91. //这种方法的优点是性能最好,因为只要一次sql交互,oracle9i也支持,缺点是只能使用Oracle jdbc特有的OraclePreparedStatement对象。  
  92. public int insertDataReturnKeyByReturnInto() throws Exception {  
  93.     Connection conn = getConnection();  
  94.     String vsql = "insert into t1(id) values(seq_t1.nextval) returning id into :1";  
  95.     OraclePreparedStatement pstmt =(OraclePreparedStatement)conn.prepareStatement(vsql);  
  96.     pstmt.registerReturnParameter(1, Types.BIGINT);  
  97.     pstmt.executeUpdate();  
  98.     ResultSet rs=pstmt.getReturnResultSet();  
  99.     rs.next();  
  100.     int id=rs.getInt(1);  
  101.     rs.close();  
  102.     pstmt.close();  
  103.     System.out.print("id:"+id);  
  104.     return id;  
  105. }  
  106. 方法简介优点缺点
    方法一先用seq.nextval取出值,然后用转入变量的方式插入代码简单直观,使用的人也最多需要两次sql交互,性能不佳
    方法二先用seq.nextval直接插入记录,再用seq.currval取出新插入的值可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码需要两次sql交互,性能不佳,并且容易产生并发安全问题
    方法三用pl/sql块的returning into语法,用CallableStatement对象设置输出参数取到新插入的值只要一次sql交互,性能较好需要采用pl/sql语法,代码不直观,使用较少
    方法四设置PreparedStatement需要返回新值的字段名,然后用getGeneratedKeys取得新插入的值性能良好,只要一次sql交互只有Oracle10g才支持,使用较少
    方法五returning into语法,用OraclePreparedStatement对象设置输出参数,再用getReturnResultSet取得新增入的值性能最好,因为只要一次sql交互,oracle9i也支持只能使用Oracle jdbc特有的OraclePreparedStatement对象

2013年10月8日 星期二

update select 指定筆數

UPDATE ORDER a
SET a.STATUS='02',a.PAY_DATE='',a.CHK_DATE=''
WHERE a.rowid in  
       (
       ---先編號完 再取編號>=2的資料,不可用rownum >=2,這樣會沒資料被撈出!  
       select RID
       from (                
            select rownum R,RID
            from
               (
               select rowid as RID  
               from ORDER
               where TEXT_1='010' AND TEXT_2='22T' AND TEXT_3='205'
               ORDER BY SN
               )
            )
        where R >=2  ---限定為第2筆(含)以後的資料