天天看點

通過shell來比較oracle和java中的字元串使用

今天在無意中看到了java字元串的一些東西,發現和oracle比較起來還是有一定的意義的,但是發現知識點準備好了,比較的時候,每一處java的變更都得重編譯運作還是不夠直覺,其實代碼中變化的部分很固定,是以嘗試寫了一個簡單的shell腳本來實作動态編譯運作,使得示範也更加直覺,使用Runtime.exec還是有一些限制。

比如我們使用一個test1.sh的腳本,這個腳本會根據輸入參數動态生成java代碼然後自動編譯運作。

echo "public class Test{ ">Test.java

echo "     public static void main (String[] args) {">>Test.java

echo "System.out.println($1);">>Test.java

echo "      }">>Test.java

echo "}" >>Test.java

$ORACLE_HOME/jdk/bin/javac Test.java

$ORACLE_HOME/jdk/bin/java Test

先來看看效果使用charAt方法

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").charAt(1)'

b

在oracle中如果想使用動态的調用就更直接了。我們假設腳本為test2.sh,基本能夠覆寫一些常用的例子。

sqlplus -s n1/n1

select $1 from dual;

EOF

來看一個類似的簡單例子

[ora11g@rac1 ~]$ ksh test2.sh "substr('abcd',1)" 

SUBS

----

abcd

這些準備工作齊了之後,我們來從Java中的字元串使用入手來比較一下oracle中對于字元串的處理。

java中有如下的一些函數,我會依次來做比較。

public char charAt(int index)

傳回字元串中第index個字元;

oracle中可以使用substr來簡單實作,需要注意兩種方式的下标,在java的charAt中是以0開始,而在oracle中的substr中則是以1開始計數的。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").charAt(2)'

c

[ora11g@rac1 ~]$ ksh test2.sh "substr('abcd',3,1)"

S

-

public int length()

傳回字元串的長度;

oracle中可以使用length函數,使用方式也是很類似的。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").length()'

4

[ora11g@rac1 ~]$ ksh test2.sh "length('abcd')"

LENGTH('ABCD')

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

             4

public int indexOf(String str)

傳回字元串中第一次出現str的位置;

oracle中可以使用instr來模拟實作,而且oracle可以更加的靈活。注意下标的不同

ksh test1.sh 'new String("abcdc").indexOf("c")'

2

[ora11g@rac1 ~]$ ksh test2.sh "instr('abcdc','c',1,1)"

INSTR('ABCDC','C',1,1)

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

                     3

順便擴充一下,oracle中如果要得到某個字元串第幾次出現的下标,相對就更直接了,比如字元串“abcdc"中第二次出現字元c的下标

[ora11g@rac1 ~]$ ksh test2.sh "instr('abcdc','c',1,2)"

INSTR('ABCDC','C',1,2)

                     5

public int indexOf(String str,int fromIndex)

傳回字元串從fromIndex開始第一次出現str的位置;

oracle中還是使用Instr,而且使用方法和上例類似。

我們對字元串abcd從下标為1,即字元b所對應的下标開始。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcdc").indexOf("c",1)'

[ora11g@rac1 ~]$ ksh test2.sh "instr('abcdc','c',2,1)"

INSTR('ABCDC','C',2,1)

public boolean equalsIgnoreCase(String another)

比較字元串與another是否一樣(忽略大小寫);

oracle中實作方式略有不同,不過可以直接轉換為大寫或者小寫即可。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").equalsIgnoreCase("abcD")'

true

SQL> select 1 from dual where upper('abcD')='ABCD';

         1

----------

public String replace(char oldchar,char newChar)

在字元串中用newChar字元替換oldChar字元

oracle中的使用也有replace函數,用法也是一緻的。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").replace("c","g")'

abgd

[ora11g@rac1 ~]$ ksh test2.sh "replace('abcd','c','g')"

REPL

public boolean startsWith(String prefix)

判斷字元串是否以prefix字元串開頭;

public boolean endsWith(String suffix)

判斷一個字元串是否以suffix字元串結尾;

oracle中的實作可以通過比對符%來實作,也可以使用正規表達式。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").startsWith("a")'

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").endsWith("d")'

SQL> select 1 from dual where 'abcd' like 'a%';

SQL> select 1 from dual where 'abcd' like '%d';

public String toUpperCase()

傳回一個字元串為該字元串的大寫形式;

public String toLowerCase()

傳回一個字元串為該字元串的小寫形式

oracle中有upper()和lower()方法,用法效果是一緻的。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd").toUpperCase()'

ABCD

[ora11g@rac1 ~]$ ksh test1.sh 'new String("ABcd").toLowerCase()'

[ora11g@rac1 ~]$ ksh test2.sh "upper('abcd')"

UPPE

[ora11g@rac1 ~]$ ksh test2.sh "lower('ABcd')"

LOWE

public String substring(int beginIndex)

傳回該字元串從beginIndex開始到結尾的子字元串;

public String substring(int beginIndex,int endIndex)

傳回該字元串從beginIndex開始到endsIndex結尾的子字元串

oracle中也有substring,相比來說功能要更豐富,注意在java中是substring,而在oracle是substr

[ora11g@rac1 ~]$ ksh test1.sh 'new String("ABcd").substring(1)'

Bcd

[ora11g@rac1 ~]$ ksh test2.sh "substr('ABcd',1)"

ABcd

[ora11g@rac1 ~]$ ksh test1.sh 'new String("ABcd").substring(1,2)'

B

[ora11g@rac1 ~]$ ksh test1.sh 'new String("ABcd").substring(1,3)'     --注意這種用法的下标,當下标為(1,3)時,才會輸出下标為1和2的字元。

Bc

[ora11g@rac1 ~]$ ksh test2.sh "substr('ABcd',1,2)"   --注意oracle中的小标是從1開始,最後的參數2代表需要截取的字元串長度為2,是以截取了AB

SU

--

AB

public String trim()

傳回該字元串去掉開頭和結尾空格後的字元串

oracle中有trim函數,而且還有ltrim,rtrim等支援的功能也要豐富一些。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd ").trim()'

[ora11g@rac1 ~]$ ksh test2.sh "trim('abcd ')"

TRIM

ltrim就是截取左邊的空白字元,rtrim就是截取右邊的空白字元。

[ora11g@rac1 ~]$ ksh test2.sh "ltrim(' abcd')"

LTRI

public String[] split(String regex)

将一個字元串按照指定的分隔符分隔,傳回分隔後的字元串數組

oracle中目前沒有發現有現成的方法實作,隻能自己DIY通過pl/sql來實作,内部也是在使用substr來遞歸解析。

下面的例子會将字元串”abcd abcd"以空格分割,最後傳回的是一個數組,我們來看看裡面的内容。

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd abcd").split(" ")[0]'

[ora11g@rac1 ~]$ ksh test1.sh 'new String("abcd abcd").split(" ")[1]'

通過pl/sql來實作網上也有不少現成的方法,得來全不費功夫。

 create or replace type tabstr_t as table of varchar2(4000);

 /

 create or replace function tabstr (

          p_str in varchar2,

          p_sep in varchar2 default ' '

          )

      return tabstr_t

      is

          l_str long := p_str || p_sep;

          l_tabstr tabstr_t := tabstr_t();

      begin

        while l_str is not null loop

            l_tabstr.extend(1);

            l_tabstr(l_tabstr.count) := rtrim(substr(

                    l_str,1,instr(l_str,p_sep)),p_sep);

            l_str := substr(l_str,instr(l_str,p_sep)+1);

        end loop;

        return l_tabstr;

    end;

 var s varchar2(100)

 exec :s := 'abcd abcd'

 select upper(column_value) from table(cast(tabstr(:s) as tabstr_t));

UPPER(COLUMN_VALUE)

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

是以通過對比的學習能夠分析出一些共同點和不同點,融會貫通還是很有用的。