2009年3月12日 星期四

Ping a server in Java

Ping a server

It's not possible to really "ping" a machine to check if it's alive or not (it's a long story, but to keep it short I will just say that the Socket class is not low-level enough for that operation). But we can emulate a ping by talking the "echo port". On a server, the echo port is always port 7. We write a string to that port and the server will echo the string.
import java.io.*;
import java.net.*;

public class PseudoPing {
public static void main(String args[]) {
try {
Socket t = new Socket(args[0], 7);
DataInputStream dis = new DataInputStream(t.getInputStream());
PrintStream ps = new PrintStream(t.getOutputStream());
ps.println("Hello");
String str = dis.readLine();
if (str.equals("Hello"))
System.out.println("Alive!") ;
else
System.out.println("Dead or echo port not responding");
t.close();
}
catch (IOException e) {
e.printStackTrace();}
}
}
}
NOTE: To make this a more "complete PING", you may want to check this How-to to display the response time.

Since JDK1.5, java.net.InetAddress.isReachable(int) can be used to check if a server is reachable or not.

import java.io.*;
import java.net.*;

public class ReachableTest {
public static void main(String args[]) {
try {
InetAddress address = InetAddress.getByName("web.mit.edu");
System.out.println("Name: " + address.getHostName());
System.out.println("Addr: " + address.getHostAddress());
System.out.println("Reach: " + address.isReachable(3000));
}
catch (UnknownHostException e) {
System.err.println("Unable to lookup web.mit.edu");
}
catch (IOException e) {
System.err.println("Unable to reach web.mit.edu");
}
}
}
isReachable() will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host. But most Internet sites have disabled the service or blocked the requests (except some university web sites like the example above) .

String host = "172.16.0.2"
int timeOut = 3000; // I recommend 3 seconds at least
boolean status = InetAddress.getByName(host).isReachable(timeOut)


source
http://www.rgagnon.com/javadetails
http://blog.wu-boy.com/2008/12/11/620/
http://www.lslnet.com/linux/f/docs1/i25/big5216009.htm

2009年3月10日 星期二

Regular Expression 基礎知識

一個規則運算式就是由普通字元(例如字元 a 到 z)以及特殊字元(稱為元字元)組成的文字模式。該模式描述在查找文字主體時待匹配的一個或多個字串。規則運算式作為一個範本,將某個字元模式與所搜索的字串進行匹配。如:

JScript

VBScript

匹配

/^\[ \t]*$/

"^\[ \t]*$"

匹配一個空白行。

/\d{2}-\d{5}/

"\d{2}-\d{5}"

驗證一個ID 號碼是否由一個2位元數字,一個連字號以及一個5位元數字組成。

/<(.*)>.*<\/\1>/

"<(.*)>.*<\/\1>"

匹配一個 HTML 標記。


下表是元字元及其在規則運算式上下文中的行為的一個完整列表:

字元

描述

\

將下一個字元標記為一個特殊字元、或一個原義字元、或一個 向後引用、或一個八進制轉義符。例如,'n' 匹配字元 "n"。'\n' 匹配一個分行符號。序列 '\\' 匹配 "\" 而 "\(" 則匹配 "("。

^

匹配輸入字串的開始位置。如果設置了 RegExp 物件的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之後的位置。

$

匹配輸入字串的結束位置。如果設置了RegExp 物件的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。

*

匹配前面的子運算式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}。

+

匹配前面的子運算式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。

?

匹配前面的子運算式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等價於 {0,1}。

{n}

n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。

{n,}

n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價於 'o+'。'o{0,}' 則等價於 'o*'。

{n,m}

m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價於 'o?'。請注意在逗號和兩個數之間不能有空格。

?

當該字元緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 後面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字串,而預設的貪婪模式則盡可能多的匹配所搜索的字串。例如,對於字串 "oooo",'o+?' 將匹配單個 "o",而 'o+' 將匹配所有 'o'。

.

匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用象 '[.\n]' 的模式。

(pattern)

匹配 pattern 並獲取這一匹配。所獲取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0…$9 屬性。要匹配圓括號字元,請使用 '\(' 或 '\)'。

(?:pattern)

匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。這在使用 "或" 字元 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的運算式。

(?=pattern)

正向預查,在任何匹配 pattern 的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字元之後開始。

(?!pattern)

負向預查,在任何不匹配 pattern 的字串開始處匹配查找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字元之後開始

x|y

匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。

[xyz]

字元集合。匹配所包含的任意一個字元。例如, '[abc]' 可以匹配 "plain" 中的 'a'。

[^xyz]

負值字元集合。匹配未包含的任意字元。例如, '[^abc]' 可以匹配 "plain" 中的'p'。

[a-z]

字元範圍。匹配指定範圍內的任意字元。例如,'[a-z]' 可以匹配 'a' 到 'z' 範圍內的任意小寫字母字元。

[^a-z]

負值字元範圍。匹配任何不在指定範圍內的任意字元。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 範圍內的任意字元。

\b

匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B

匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

\cx

匹配由 x 指明的控制字元。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字元。

\d

匹配一個數位字元。等價於 [0-9]。

\D

匹配一個非數位字元。等價於 [^0-9]。

\f

匹配一個換頁符。等價於 \x0c 和 \cL。

\n

匹配一個分行符號。等價於 \x0a 和 \cJ。

\r

匹配一個回車符。等價於 \x0d 和 \cM。

\s

匹配任何空白字元,包括空格、定位字元、換頁符等等。等價於 [ \f\n\r\t\v]。

\S

匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。

\t

匹配一個定位字元。等價於 \x09 和 \cI。

\v

匹配一個垂直定位字元。等價於 \x0b 和 \cK。

\w

匹配包括底線的任何單詞字元。等價於'[A-Za-z0-9_]'。

\W

匹配任何非單詞字元。等價於 '[^A-Za-z0-9_]'。

\xn

匹配 n,其中 n 為十六進位轉義值。十六進位轉義值必須為確定的兩個數位長。例如,'\x41' 匹配 "A"。'\x041' 則等價於 '\x04' & "1"。規則運算式中可以使用 ASCII 編碼。.

\num

匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。例如,'(.)\1' 匹配兩個連續的相同字元。

\n

標識一個八進制轉義值或一個向後引用。如果 \n 之前至少 n 個獲取的子運算式,則 n 為向後引用。否則,如果 n 為八進位數字 (0-7),則 n 為一個八進制轉義值。

\nm

標識一個八進制轉義值或一個向後引用。如果 \nm 之前至少有 nm 個獲得子運算式,則 nm 為向後引用。如果 \nm 之前至少有 n 個獲取,則 n 為一個後跟文字 m 的向後引用。如果前面的條件都不滿足,若 n 和 m 均為八進位數字 (0-7),則 \nm 將匹配八進制轉義值 nm。

\nml

如果 n 為八進位數字 (0-3),且 m 和 l 均為八進位數字 (0-7),則匹配八進制轉義值 nml。

\un

匹配 n,其中 n 是一個用四個十六進位數位表示的 Unicode 字元。例如, \u00A9 匹配版權符號 (©)。


下面看幾個例子:
"^The"
:表示所有以"The"開始的字串("There","The cat"等);
"of despair$"
:表示所以以"of despair"結尾的字串;
"^abc$"
:表示開始和結尾都是"abc"的字串——呵呵,只有"abc"自己了;
"notice"
:表示任何包含"notice"的字串。

'*'
,'+'和'?'這三個符號,表示一個或一序列字元重複出現的次數。它們分別表示“沒有或
更多”,“一次或更多”還有“沒有或一次”。下面是幾個例子:

"ab*":表示一個字串有一個a後面跟著零個或若干個b。("a", "ab", "abbb",……);
"ab+"
:表示一個字串有一個a後面跟著至少一個b或者更多;
"ab?"
:表示一個字串有一個a後面跟著零個或者一個b;
"a?b+$"
:表示在字串的末尾有零個或一個a跟著一個或幾個b。

也可以使用範圍,用大括弧括起,用以表示重複次數的範圍。

"ab{2}":表示一個字串有一個a跟著2個b("abb");
"ab{2,}"
:表示一個字串有一個a跟著至少2個b;
"ab{3,5}"
:表示一個字串有一個a跟著3到5個b。

請注意,你必須指定範圍的下限(如:"{0,2}"而不是"{,2}")。還有,你可能注意到了,'*','+'和
'?'
相當於"{0,}","{1,}"和"{0,1}"。
還有一個'¦',表示“或”操作:

"hi¦hello":表示一個字串裡有"hi"或者"hello";
"(b¦cd)ef"
:表示"bef"或"cdef";
"(a¦b)*c"
:表示一串"a""b"混合的字串後面跟一個"c";

'.'可以替代任何字元:

"a.[0-9]":表示一個字串有一個"a"後面跟著一個任意字元和一個數位;
"^.{3}$"
:表示有任意三個字元的字串(長度為3個字元);

方括號表示某些字元允許在一個字串中的某一特定位置出現:

"[ab]":表示一個字串有一個"a"或"b"(相當於"a¦b");
"[a-d]"
:表示一個字串包含小寫的'a'到'd'中的一個(相當於"a¦b¦c¦d"或者"[abcd]");
"^[a-zA-Z]"
:表示一個以字母開頭的字串;
"[0-9]%"
:表示一個百分號前有一位元的數字;
",[a-zA-Z0-9]$"
:表示一個字串以一個逗號後面跟著一個字母或數位結束。

你也可以在方括號裡用'^'表示不希望出現的字元,'^'應在方括號裡的第一位。(如:"%[^a-zA-Z]%"表
示兩個百分號中不應該出現字母)。

為了逐字表達,必須在"^.$()¦*+?{\"這些字元前加上轉移字元'\'。

請注意在方括號中,不需要轉義字元。

source: http://hi.baidu.com/ismayday/blog

2009年3月4日 星期三

Write Java WebStart Application in 5 minutes

They say, the best way of learning is to do-it-yourself. When I was assigned to write an article on Java Webstart, I thought to truly understand what's happening with Java Web Start, let's create a program and try to deploy it through any web server.

Pre-requisities

  1. You need to have the latest version of JDK installed on your system before you can proceed. We use JDK 1.6. Here is a guide to install JDK 1.6 / Java SE 6 in Linux under 5 minutes.
  2. You will ideally need a source code editor like JEdit. At the least use notepad or vi (on *nix) to edit the source code. Do not use any word processing programs like Microsoft Word or Open Office Writer.
  3. Create a Java file that you want to run using JNLP. This can be a regular Swing or AWT based application. It can even be a console application if you wish.
  4. Compile and test your source code(s) as you would with a regular program.

Create a Jar file

Java Web Start applications need to be packaged within a jar file. You can create a .jar file from your class file(s) using this command (assume you class file is named Test.class):

   jar cvf test.jar Test.class
Note: v is for verbose mode. You can omit it if you want.

Create a key

You need to create a keystore which will then be used to sign the jar files:

      keytool -genkey -keystore myKeys -alias jdc

When prompted, fill in your name. You can skip the other details if you want.

Note: myKeys is the name of your keystore. You will need it in the next step to sign the jar file(s).

Now let's sign the jar file(s)

Run the command below to sign the jar file. When prompted for password, give it a six letter, easy to remember (just for demo not for production) password.

 jarsigner -keystore myKeys *.jar jdc

Create a JNLP file

jnlp

A JNLP file provides the specification for your Java Web Start application. We will not cover the details of a JNLP file in this brief guide. However we will provide you with a simple jnlp file which you can use for many occassions. JNLP file is in XML format. Use a source code editor to edit the file. Let's save it as test.jnlp on the document root of your local web server. You can use JWS, a simple web server that ships with Java Web Start, Apache, Tomcat or any other web server. The web server itself doesn't need any special capability to serve Java Web Start applications.

Note:

1. The main-class (test) is the main class of your application
2. We have used to allow the JNLP application to access all client resource. This is not something you may want to do in production environment. In production you should only ask for permissions that you really need to give customers peace of mind. Check the documentation of j2ee-application-client-permissions for details.

Create html file and run the baby!

Create a html file in the same location as the other files containing just the link to your jnlp file on your web server like say http://localhost/test.jnlp in this example. Now gather around your peers and boss (if you are feeling adventurous) and open the html file you just created in any browser. You will be prompted to open it in Java Web Start. Agree to it and also agree to any subsequent message asking you to grant permission to the application.

That's it guys! Wasn't that easy?


source: http://blog.taragana.com/

2009年3月1日 星期日

Oracle SQL裡常用的時間函數

Oracle SQL裡常用的時間函數,經典推薦

相信很多人都有過統計某些數據的經歷,比如,要統計財務的情況,可能要按每年,每季度,每月,甚至每個星期來分別統計。 那在oracle中應該怎麼來寫sql語句呢,這個時候Oracle的日期函數會給我們很多幫助。

常用日期型函數
1。 Sysdate當前日期和時間
SQL> Select sysdate from dual;

SYSDATE
----------
21-6月-05

2。 Last_day本月最後一天
SQL> Select last_day(sysdate) from dual;

LAST_DAY(S
----------
30-6月-05

3。 Add_months(d,n)當前日期d後推n個月用於從一個日期值增加或減少一些月份
date_value:=add_months(date_value,number_of_months)

SQL> Select add_months(sysdate,2) from dual;

ADD_MONTHS
----------
21-8月-05

4。 Months_between(f,s)日期f和s間相差月數
SQL> select months_between(sysdate,to_date('2005-11-12','yyyy-mm-dd'))from dual;

MONTHS_BETWEEN(SYSDATE,TO_DATE('2005-11-12','YYYY-MM-DD'))
-------------------------------------------------- --------
-4.6966741

5。 NEXT_DAY(d, day_of_week)
返回由"day_of_week"命名的,在變量"d"指定的日期之後的第一個工作日的日期。 參數"day_of_week"必須為該星期中的某一天。
SQL> SELECT next_day(to_date('20050620','YYYYMMDD'),1) FROM dual;

NEXT_DAY(T
----------
26-6月-05

6。 current_date()返回當前會話時區中的當前日期
date_value:=current_date
SQL> column sessiontimezone for a15
SQL> select sessiontimezone,current_date from dual;

SESSIONTIMEZONE CURRENT_DA
--------------- ----------
+08:00 13-11月-03


SQL> alter session set time_zone='-11:00' 2 /
會話已更改。

SQL> select sessiontimezone,current_timestamp from dual;

SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ----------------------------------- -
-11:00 12-11月-03 04.59.13.668000下午-11:00

7。 current_timestamp()以timestamp with time zone數據類型返回當前會話時區中的當前日期
SQL> select current_timestamp from dual;

CURRENT_TIMESTAMP
-------------------------------------------------- -------------------------
21-6月-05 10.13.08.220589上午+08:00

8。 dbtimezone()返回時區
SQL> select dbtimezone from dual;

DBTIME
------
-08:00

9。 extract()找出日期或間隔值的字段值
date_value:=extract(date_field from [datetime_value|interval_value])
SQL> select extract(month from sysdate) "This Month" from dual;

This Month
----------
6

SQL> select extract(year from add_months(sysdate,36)) " Years" from dual;

Years
----------
2008

10。 localtimestamp()返回會話中的日期和時間
SQL> select localtimestamp from dual;

LOCALTIMESTAMP
-------------------------------------------------- -------------------------
21-6月-05 10.18.15.855652上午

11。取得week number
TO_CHAR(TO_DATE('2007/05/16','YYYY/MM/DD'),'IW') AS WEEK




常用日期數據格式(該段為摘抄)

Y或YY或YYY年的最後一位,兩位或三位Select to_char(sysdate,’YYY’) from dual; 002表示2002年
SYEAR或YEAR SYEAR使公元前的年份前加一負號Select to_char(sysdate,’SYEAR’) from dual; -1112表示公元前111 2年
Q季度,1~3月為第一季度Select to_char(sysdate,’Q’) from dual; 2表示第二季度①
MM月份數Select to_char(sysdate,’MM’) from dual; 12表示12月
RM月份的羅馬錶示Select to_char(sysdate,’RM’) from dual; IV表示4月
Month用9個字符長度表示的月份名Select to_char(sysdate,’Month’) from dual; May後跟6個空格表示5月
WW當年第幾週Select to_char(sysdate,’WW’) from dual; 24表示2002年6月13日為第24週
W本月第幾週Select to_char(sysdate,’W’) from dual; 2002年10月1日為第1週
DDD當年第幾, 1月1日為001,2月1日為032 Select to_char(sysdate,’DDD’) from dual; 363 2002年1 2月2 9日為第363天
DD當月第幾天Select to_char(sysdate,’DD’) from dual; 04 10月4日為第4天
D週內第幾天Select to_char(sysdate,’D’) from dual; 5 2002年3月14日為星期一
DY週內第幾天縮寫Select to_char(sysdate,’DY’) from dual; SUN 2002年3月24日為星期天
HH或HH12 12進制小時數Select to_char(sysdate,’HH’) from dual; 02午夜2點過8分為02
HH24 24小時制Select to_char(sysdate,’HH24’) from dual; 14下午2點08分為14
MI分鐘數(0~59) Select to_char(sysdate,’MI’) from dual; 17下午4點17分
SS秒數(0~59) Select to_char(sysdate,’SS’) from dual; 22 11點3分22秒提示注意不要將MM格式用於分鐘(分鐘應該使用MI)。 MM是用於月份的格式,將它用於分鐘也能工作,但結果是錯誤的。


現在給出一些實踐後的用法:

1。 上月末天:
SQL> select to_char(add_months(last_day(sysdate),-1),'yyyy-MM-dd') LastDay from dual;

LASTDAY
----------
2005-05-31

2。 上月今天
SQL> select to_char(add_months(sysdate,-1),'yyyy-MM-dd') PreToday from dual;


PRETODAY
----------
2005-05-21

3.上月首天
SQL> select to_char(add_months(last_day(sysdate)+1,-2),'yyyy-MM-dd') firstDay from dual;

FIRSTDAY
----------
2005-05-01

4.按照每週進行統計
SQL> select to_char(sysdate,'ww') from dual group by to_char(sysdate,'ww');

TO
--
25

5。 按照每月進行統計
SQL> select to_char(sysdate,'mm') from dual group by to_char(sysdate,'mm');

TO
--
06

6。 按照每季度進行統計
SQL> select to_char(sysdate,'q') from dual group by to_char(sysdate,'q');

T
-
2

7。 按照每年進行統計
SQL> select to_char(sysdate,'yyyy') from dual group by to_char(sysdate,'yyyy');

TO_C
----
2005

8.要找到某月中所有周五的具體日期
select to_char(td,'YY-MM-DD') from (
select trunc(sysdate, 'MM')+rownum-1 as d
from dba_objects
where rownum <>

and trim(to_char(td, 'Day')) = '星期五'
--------
03-05-02
03-05-09
03-05-16
03-05-23
03-05-30

如果把where to_char(td, 'MM') = to_char(sysdate, 'MM')改成sysdate-90,即為查找當前月份的前三個月中的每週五的日期。

9.oracle中時間運算

內容如下:
1、oracle支持對日期進行運算
2、日期運算時是以天為單位進行的
3、當需要以分秒等更小的單位算值時,按時間進制進行轉換即可
4、進行時間進制轉換時注意加括號,否則會出問題

SQL> alter session set nls_date_format='yyyy-mm-dd hh:mi:ss';

會話已更改。

SQL> set serverout on
SQL> declare
2 DateValue date;
3 begin
4 select sysdate into DateValue from dual;
5 dbms_output.put_line('原時間:'||to_char(DateValue));
6 dbms_output.put_line('原時間減1天:'||to_char(DateValue-1));
7 dbms_output.put_line('原時間減1天1小時:'||to_char(DateValue-1-1/24));
8 dbms_output.put_line('原時間減1天1小時1分:'||to_char(DateValue-1-1/24-1/(24*60)));
9 dbms_output.put_line('原時間減1天1小時1分1秒:'||to_char(DateValue-1-1/24-1/(24*60)-1/(24*60*60))) ;
10 end;
11 /
原時間:2003-12-29 11:53:41
原時間減1天:2003-12-28 11:53:41
原時間減1天1小時:2003-12-28 10:53:41
原時間減1天1小時1分:2003-12-28 10:52:41
原時間減1天1小時1分1秒:2003-12-28 10:52:40

PL/SQL過程已成功完成。


在Oracle中實現時間相加處理
--名稱:Add_Times
--功能:返回d1與NewTime相加以後的結果,實現時間的相加
--說明:對於NewTime中的日期不予考慮
--日期:2004-12-07
--版本:1.0
--作者:Kevin


create or replace function Add_Times(d1 in date,NewTime in date) return date
is
hh number;
mm number;
ss number;
hours number;
dResult date;
begin
--下面依次取出時、分、秒
select to_number(to_char(NewTime,'HH24')) into hh from dual;
select to_number(to_char(NewTime,'MI')) into mm from dual;
select to_number(to_char(NewTime,'SS')) into ss from dual;
--換算出NewTime中小時總和,在一天的百分幾
hours := (hh + (mm / 60) + (ss / 3600))/ 24;
--得出時間相加後的結果
select d1 + hours into dResult from dual;
return(dResult);
end Add_Times;


--測試用例
-- select Add_Times(sysdate,to_date('2004-12-06 03:23:00','YYYY-MM-DD HH24:MI:SS')) from dual


在Oracle9i中計算時間差計算時間差是Oracle DATA數據類型的一個常見問題。 Oracle支持日期計算,你可以創建諸如“日期1-日期2”這樣的表達式來計算這兩個日期之間的時間差。


一旦你發現了時間差異,你可以使用簡單的技巧來以天、小時、分鐘或者秒為單位來計算時間差。 為了得到數據差,你必須選擇合適的時間度量單位,這樣就可以進行數據格式隱藏。

使用完善複雜的轉換函數來轉換日期是一個誘惑,但是你會發現這不是最好的解決方法。

round(to_number(end-date-start_date))-消逝的時間(以天為單位)

round(to_number(end-date-start_date)*24)-消逝的時間(以小時為單位)

round(to_number(end-date-start_date)*1440)-消逝的時間(以分鐘為單位)

顯示時間差的默認模式是什麼? 為了找到這個問題的答案,讓我們進行一個簡單的SQL *Plus查詢。

SQL> select sysdate-(sysdate-3) from dual;

SYSDATE-(SYSDATE-3)
-------------------
3

這裡,我們看到了Oracle使用天來作為消逝時間的單位,所以我們可以很容易的使用轉換函數來把它轉換成小時或者分鐘。 然而,當分鐘數不是一個整數時,我們就會遇到放置小數點的問題。

Select
(sysdate-(sysdate-3.111))*1440
from
dual;

(SYSDATE-(SYSDATE-3.111))*1440
------------------------------
4479.83333

當然,我們可以用ROUND函數(即取整函數)來解決這個問題,但是要記住我們必須首先把DATE數據類型轉換成NUMBER數據類型。

Select
round(to_number(sysdate-(sysdate-3.111))*1440)
from
dual;

ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)
----------------------------------------------
4480

我們可以用這些函數把一個消逝時間近似轉換成分鐘並把這個值寫入Oracle表格中。 在這個例子裡,我們有一個離線(logoff)系統級觸發機制來計算已經開始的會話時間並把它放入一個Oracle STATSPACK USER_LOG擴展表格之中。

Update
perfstat.stats$user_log
set
elapsed_minutes =
round(to_number(logoff_time-logon_time)*1440)
where
user = user_id
and
elapsed_minutes is NULL;

查出任一年月所含的工作日
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*------------------------------------------------ ------------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日作者姓名: XINGPING
編寫時間: 2004-05-22
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返回值:整型值,包含的工作日數目。
算法描述:
1).列舉出參數給出的年月中的每一天。 這裡使用了一個表(ljrq是我的庫中的一張表。這個表可以是有權訪問的、記錄條數至少為31的任意一張表或視圖)來構造出某年月的每一天。
2).用這些日期和一個已知星期幾的日期相減(2001-12-30是星期天),所得的差再對7求模。 如果所求年月在2001-12-30以前,那麼所得的差既是負數,求模後所得值範圍為大於-6,小於0,如-1表示星期六,故先將求模的結果加7,再求7的模.
3).過濾掉結果集中值為0和6的元素,然後求count,所得即為工作日數目。
-------------------------------------------------- -----------------------------------------------*/
Result INTEGER;
BEGIN
SELECT COUNT(*) INTO Result
FROM (SELECT MOD(MOD(q.rq-to_date('2001-12-30','yyyy-mm-dd'),7),7) weekday
FROM ( SELECT to_date(ny||t.dd,'yyyymmdd') rq
FROM (SELECT substr(100+ROWNUM,2,2) dd
FROM ljrq z WHERE Rownum<=31 ) t WHERE to_date(ny||t.dd,'yyyymmdd') BETWEEN to_date(ny,'yyyymm') AND last_day(to_date(ny,'yyyymm')) )q ) a WHERE a.weekday NOT IN(0,6); RETURN Result; END Get_WorkingDays;

______________________________________

還有一個版本
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*------------------------------------------------ -----------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日作者姓名: XINGPING
編寫時間: 2004-05-23
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返回值:整型值,包含的工作日數目。
算 法描述:使用Last_day函數計算出參數所給年月共包含多少天,根據這個值來構造一個循環。 在這個循環中先求這個月的每一天與一個已知是星期天的日期(2001-12-30是星期天)的差,所得的差再對7求模。 如果所求日期在2001-12-30以前,那麼所得的差既是負數,求模後所得值範圍為大於-6,小於0,如-1表示星期六,故先將求模的結果加7,再求7 的模.如過所得值不等於0和6(即不是星期六和星期天),則算一個工作日。
-------------------------------------------------- --------------------------------------*/
Result INTEGER := 0;
myts INTEGER; --所給年月的天數
scts INTEGER; --某天距2001-12-30所差的天數
rq DATE;
djt INTEGER := 1; --
BEGIN
myts := to_char(last_day(to_date(ny,'yyyymm')),'dd');
LOOP
rq := TO_date(ny||substr(100+djt,2),'yyyymmdd');
scts := rq - to_date('2001-12-30','yyyy-mm-dd');
IF MOD(MOD(scts,7)+7,7) NOT IN(0,6) THEN
Result := Result + 1;
END IF;
djt := djt + 1;
EXIT WHEN djt>myts;
END LOOP;
RETURN Result;
END Get_WorkingDays;

以上兩個版本的比較

第一個版本一條SQL語句就可以得出結果,不需要編程就可以達到目的。 但需要使用任意一張有權訪問的、記錄條數至少為31的一張表或視圖。
第二個版本需要編程,但不需要表或者視圖。
這兩個版本都還存在需要完善的地方,即沒有考慮節日,如五一、十一、元旦、春節這些節假期都沒有去除。 這些節假日應該維護成一張表,然後通過查表來去除這些節假日。

求一段連續日期,但排除六日
自已標記一下,方便以後查尋

select allday from (
select to_date('2007-02-15','yyyy-mm-dd')+rownum allday from
(select to_date('2007-02-15','yyyy-mm-dd'),to_date('2007-02-28','yyyy-mm-dd') from dual)
connect by rownum <>1 and to_char(allday,'D') <7>



source: http://oracled2k.pixnet.net/blog

2009年2月4日 星期三

The differences between Truncate, Delete and Drop

Truncate, Delete, Drop的異同點

注意:這裡說的delete是指不帶where子句的delete語句

相同點
truncate和不帶where子句的delete,以及drop都會刪除表內的數據

不同點:
1. truncate和delete只刪除數據不刪除表的結構(By Definition)
drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger),索引(index);依賴於該表的存儲過程/函數將保留,但是變為invalid狀態.

2.delete語句是dml,這個操作會放到rollback segement中,事務提交之後才生效;如果有相應的trigger,執行的時候將被觸發.
truncate,drop是ddl,操作立即生效,原數據不放到rollback segment中,不能回滾.操作不觸發trigger.

3.delete語句不影響表所佔用的extent,高水線(high watermark)保持原位置不動
顯然drop語句將表所佔用的空間全部釋放 ;
truncate語句缺省情況下見空間釋放到minextents個extent,除非使用reuse storage; truncate會將高水線復位(回到最開始).
4.速度,一般來說: drop>; truncate >; delete
5.安全性:小心使用drop和truncate,尤其沒有備份的時候.否則哭都來不及
使用上,想刪除部分數據行用delete,注意帶上where子句.回滾段要足夠大.
想刪除表,當然用drop
想保留表而將所有數據刪除.如果和事務無關,用truncate即可.如果和事務有關,或者想觸發trigger,還是用delete.
如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新導入/插入數據

事務中的DDL語句會引起COMMIT的, Truncate是不會全部釋放存儲空間!
Drop會釋放存儲空間!

Source: http://bbs.chinaunix.net/viewthread.php?tid=252763

2009年1月29日 星期四

權限設計參考

遲d整理, 睇住先
http://www.cnblogs.com/a7345678/archive/2008/09/25/1298838.html
http://www.blogjava.net/amigoxie/archive/2007/09/29/149509.html
http://www.cnblogs.com/yukaizhao/archive/2007/04/15/user_role_action_permission.html
http://www.blogjava.net/RongHao/category/20773.html

2009年1月20日 星期二

DBCP, C3P0常用參數,和使用中碰到的問題

DBCP:
driverClassName
url
username
password
上面四個分別是驅動,連接字符串,用戶名和密碼

maxActive連接池支持的最大連接數
maxIdle連接池中最多可空閒maxIdle個連接
minIdle連接池中最少空閒maxIdle個連接
initialSize初始化連接數目
maxWait連接池中連接用完時,新的請求等待時間,毫秒
timeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis和minEvictableIdleTimeMillis一起使用,每

timeBetweenEvictionRunsMillis毫秒秒檢查一次連接池中空閒的連接,把空閒時間超過minEvictableIdleTimeMillis毫秒的連接斷開,直到連接池中的連接數到minIdle為止

minEvictableIdleTimeMillis連接池中連接可空閒的時間,毫秒

removeAbandoned true,false,是否清理removeAbandonedTimeout秒沒有使用的活動連接,清理後並沒有放回連接池
removeAbandonedTimeout活動連接的最大空閒時間
logAbandoned true,false,連接池收回空閒的活動連接時是否打印消息


minEvictableIdleTimeMillis,removeAbandonedTimeout這兩個參數針對的連接對像不一樣,minEvictableIdleTimeMillis針對連接池中的連接對象,removeAbandonedTimeout針對未被close的活動連接.

在dbcp使用中遇到的問題:
當短時間之內活動連接達到maxActive,再請求連接,等maxWait秒後連接池就會報出錯來:Cannot get a connection, pool exhausted.在這maxWait秒裡removeAbandoned並沒有起作用,出錯後連接池就會把所有的連接斷開,為什麼這時候 removeAbandoned沒有起作用呢?


C3P0:
http://sourceforge.net/projects/c3p0 (c3p0-src - c3p0-0.9.1.2)
driverClass
jdbcUrl
user
password
minPoolSize
maxPoolSize
initialPoolSize

acquireIncrement池中沒有空閒連接時,一次請求獲取的連接數
maxIdleTime池中連接最大空閒時間
acquireRetryAttempts獲取連接失敗後,重新嘗試的次數
acquireRetryDelay嘗試連接間隔時間,毫秒
checkoutTimeout等待連接時間,0為無限等待,毫秒
DebugUnreturnedConnectionStackTraces true,false,是否收回未返回的活動連接
unreturnedConnectionTimeout活動連接的時間.

c3p0中的問題:
unreturnedConnectionTimeout是給每個活動連接一個時間限制,到點兒就收回,不管有沒有正在使用連接.這樣不是太好,應該是從最後一次使用連接才開始計時才好.那有沒有這樣的一個參數從最後一次使用計時呢?

source:
http://www.javaeye.com/post/607253
http://www.hibernate.org/214.html
For C3P0
http://www.hibernate.org/214.html?cmd=comphist&histnode=1059