對於想了解PostgreSQL Transaction 或是進階開發 Java EE 有關 JTA 的新人,
建議必要對該內容有個初步的認識.
(點圖大放後再保存)

全球最先進的開放源碼資料庫系統! PostgreSQL 以全球最自由且不受用途限制的 BSD 授權協議發佈, 擁有龐大的全球開發者/用戶社群, PostgreSQL 為企業級應用特性亦完整且高度相容於 ISO/ANSI SQL 國際標準, 高可用性(HA)及數據儲存品質倫美與持續超越 Oracle, DB2... 等商業型資料庫管理系統, TOC(整體擁有成本)更遠低於商業型 DBMS 達數百倍.
PL/pgSQL 是 PostgreSQL 內置的可選預儲程序(Stored Procured)語言之一, 也是當中的效能與功能最強的。在這系列我們將學習如何撰寫 PL/pgSQL 的存儲函數/函式(Function)。
所有的 PL/pgSQL 函數遵循的結構, 看起來都如同下面的形式。
CREATE OR REPLACE FUNCTION fnsomefunc(numtimes integer, msg text)
RETURNS text AS
$
DECLARE
strresult text;
BEGIN
strresult := '';
IF numtimes > 0 THEN
FOR i IN 1 .. numtimes LOOP
strresult := strresult || msg || E'\r\n';
END LOOP;
END IF;
RETURN strresult;
END;
$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER
COST 10;
-- 我們呼叫這個函數它將回傳10次'hello there's'且回傳處理於單一的文本(text)欄位中.
SELECT fnsomefunc(10, 'Hello there');
這個 PL/pgSQL 函數的基本構成如下:
PL/pgSQL 對條件限制的邏輯式是成對的結構. 在上面的範例中我們看到了簡單的 IF THEN。同樣也存在於 IF .. ELSIF ..ELSIF END IF, IF ..ELSE ..END IF。我們將在上面的示例上做一個改變。
CREATE OR REPLACE FUNCTION fnsomefunc(numtimes integer, msg text)
你說得對!
RETURNS text AS
$
DECLARE
strresult text;
BEGIN
strresult := '';
IF numtimes = 42 THEN
strresult := '';
你不能這樣做。麻煩不要濫用我們的慷慨。
ELSIF numtimes > 0 AND numtimes < 100 THEN
FOR i IN 1 .. numtimes LOOP
strresult := strresult || msg || E'\r\n';
END LOOP;
ELSE
strresult := '';
。
IF numtimes <= 0 THEN
strresult := strresult || '你是一個 bozo';
我不知道你以為你是誰。
ELSIF numtimes > 1000 THEN
strresult := strresult || '。
你的意向失去了控制';
END IF;
END IF;
RETURN strresult;
END;
$
LANGUAGE 'plpgsql' IMMUTABLE;
SELECT fnsomefunc(42, 'Hello there');
SELECT fnsomefunc(200, 'Hello there');
SELECT fnsomefunc(5000, 'Hello there');
在 PL/pgSQL 中提供的基本控制流結構是:
此外 NTT 也投入參加 PostgreSQL 資料庫系統的研發。"發布於 2008年2月 的最新版本的 PostgreSQL 8.3 中有三個最大的改良設計專案, 當中的二項就是 NTT 所做的貢獻"(NTT OSS 中心主任-木ノ原誠司氏)。
具體來說,是 PostgreSQL 內部自動最佳化 Data 的配置和改良的功能,以及 Data 寫入到實體儲存體和負載均衡(LB)。此外,NTT 共有 45項提出改進程序碼,以及日文全文檢索的工具 - textsearch-ja,能大幅削減交易日誌歸檔容量能力的 pglesslog ,高速裝載大量 Data 的工具 - pg_bulkload。
日本 NTT 估算該公司在5年內至少可達到削減累計約 20-30億日元(折合新台幣約 5億元)的成效,降低 NTT TCO(資訊化整體擁有成本)。
"在當前的 PostgreSQL 8.3 中 1TB(terabyte) datas,可達99.99%的可用性/可靠性的高要求(故障時系統的更替時間可在5分鐘內)"-(日本 NTT OSS事業化推進PT 担当部長 館剛司氏)。
預計將在 2011年財政年度,10TB,能提供高達 99.999% (故障時系統的更替時間可在1分鐘內),可用於顧客付費相關的主系統。透過這些過程,"在未來5年內, PosgtreSQL 可預期的導入程度可有 25% 的增長速度。在這樣成長、擴展的過程中,可削減約 20-30億日元"- (NTT 木ノ原氏)。
另外,在 2008年宣布在9月2日為 SaaS 的商業服務也將適用於該基金會。EnterpriseDB 公司將公開其研究開發的開放源碼一個平行處理技術 - GridSQL, NTT 與 PostgtreSQL 共同發展社群和提供改良建議,結合同步複寫技術,開發 PostgreSQL 的大規模分佈式數據庫技術。
NTT對EnterpriseDB 公司的出資金額與比例是屬於非公開的事項。在日本,Cntents、Lgistique、Linux是EnterpriseDB 公司的代理商,而 EnterpriseDB 公司也以「想要在日本增加所屬的代理商」為由,已經向多數廠商進行交涉合作中。而NTT也正極力研討加入所屬代理商的可能性。
public static long currentTimeMillis()
請參閱 Date
類別的描述,瞭解可能發生在“計算機時間”和協調世界時(UTC)之間的細微差異的討論。
Date
public static TimeZone getDefault()
TimeZone
。預設 TimeZone
的來源可能隨實作的變化而變化。
TimeZone
。 setDefault(java.util.TimeZone)
public static Locale getDefault()
Java 虛擬機器根據主機的環境在啟動期間設置預設語言環境。如果沒有明確地指定語言環境,則很多語言環境敏感的方法都使用該方法。可使用 setDefault
方法更改該值。
public class Date
一個套件裝了毫秒值的瘦外覆類別 (thin wrapper),它允許 JDBC 將毫秒值標識為 SQL DATE
值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來經過的毫秒數。
為了與 SQL DATE
的定義一致,由 java.sql.Date
實例包裹的毫秒值必須通過將小時、分鐘、秒和毫秒設置為與該實例相關的特定時區中的零來“規範化”。
public class Time
一個與 java.util.Date
類別有關的瘦外覆類別 (thin wrapper),它允許 JDBC 將該類別標識為 SQL TIME
值。Time
類別添加格式化和解析操作以支持時間值的 JDBC 轉義語法。
應該將日期元件設置為 1970 年 1 月 1 日的 "zero epoch" 值並且不應存取該值。
public class Timestamp
一個與 java.util.Date
類別有關的瘦外覆類別 (thin wrapper),它允許 JDBC API 將該類別標識為 SQL TIMESTAMP
值。它通過允許小數秒到納秒級精度的規範來添加保存 SQL TIMESTAMP
小數秒值的能力。Timestamp 也提供支持時間戳值的 JDBC 轉義語法的格式化和解析操作的能力。
計算 Timestamp 物件的精度為二者之一:
19
,其為 yyyy-mm-dd hh:mm:ss 格式下的字元數 20 + s
,其為 yyyy-mm-dd hh:mm:ss.[fff...] 格式下的字元數,s
表示給定 Timestamp 的標度(其小數秒精度)。註:此型別由 java.util.Date
和單獨的毫微秒值組成。只有整數秒才會存儲在 java.util.Date
元件中。小數秒(毫微秒)是獨立存在的。傳遞不是 java.sql.Timestamp
實例的物件時,Timestamp.equals(Object)
方法永遠不會返回 true
,因為日期的毫微秒元件是未知的。因此,相對於 java.util.Date.equals(Object)
方法而言,Timestamp.equals(Object)
方法是不對稱的。此外,hashcode
方法使用底層 java.util.Date
實作並因此在其計算中不包括毫微秒。
鑒於 Timestamp
類別和上述 java.util.Date
類別之間的不同,建議程式碼一般不要將 Timestamp
值視為 java.util.Date
的實例。Timestamp
和 java.util.Date
之間的繼承關係實際上指的是實作繼承,而不是型別繼承。
void setDate(int parameterIndex,
Date x)
throws SQLException
java.sql.Date
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQL DATE
值。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 參數值 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的 PreparedStatement
上調用此方法void setTimestamp(int parameterIndex,
Timestamp x)
throws SQLException
java.sql.Timestamp
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQL TIMESTAMP
值。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 參數值 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的 PreparedStatement
上調用此方法void setTime(int parameterIndex,
Time x)
throws SQLException
java.sql.Time
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQL TIME
值。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 參數值 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的 PreparedStatement
上調用此方法Java Types | 自己產生時間 | 存入PostgreSQL資料庫的對應型別 |
java.util.Date | T | 需要包覆 |
java.util.Calendar | T | 需要包覆 |
java.sql.Date | F | date |
java.sql.Time | F | time |
java.sql.Timestamp | F | timestamp |
void setBinaryStream(int parameterIndex,
InputStream x)
throws SQLException
LONGVARBINARY
參數時,通過 java.io.InputStream
物件發送它可能更為實際。將根據需要從串流中讀取資料,一直讀取到檔案末尾。 註:此串流物件既可以是一個標準 Java 串流物件,也可以是實作標準介面的使用者自己的子類別。
註:查詢 JDBC 驅動程序文檔,以確定使用帶 length 參數的 setBinaryStream
是否更有效。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 套件含二進制參數值的 java 輸入串流 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;PreparedStatement
上調用此方法 SQLFeatureNotSupportedException
- 如果 JDBC 驅動程序不支持此方法 void setBinaryStream(int parameterIndex,
InputStream x,
int length)
throws SQLException
LONGVARBINARY
參數時,java.io.InputStream
物件發送它可能更為實際。註:此串流物件既可以是一個標準 Java 串流物件,
也可以是實作標準介面的使用者自己的子類別。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 套件含二進制參數值的 Java 輸入串流 length
- 串流中的位元組數 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;PreparedStatement
上調用此方法void setBinaryStream(int parameterIndex,
InputStream x,
long length)
throws SQLException
LONGVARBINARY
參數時,java.io.InputStream
物件發送它可能更為實際。註:此串流物件既可以是一個標準 Java 串流物件,
也可以是實作標準介面的使用者自己的子類別。
parameterIndex
- 第一個參數是 1,第二個參數是 2,…… x
- 套件含二進制參數值的 java 輸入串流 length
- 串流中的位元組數 SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;PreparedStatement
上調用此方法 Java Types | PostgreSQL Types |
布林型別 | |
boolean | boolean |
Boolean | |
字元型別 | |
String(char , Character) | character |
character varying | |
text | |
整數型別 | |
byte | integer(smallint) |
Byte | |
short | |
Short | |
int | |
Integer | |
long | bigint |
Long | |
浮點數型別 | |
float | double precision (real) |
Float | |
double | |
Double | |
時間型別 | |
java.util.Date | date,time,timestamp |
java.util.Calendar | |
二進制檔案 | |
.gif | bytea |
.jpg | |
.png | |
.mp3 | |
序列化資料 | |
SerializableData (SampleData(Object)) | bytea |
Java Types | PostgreSQL Types | 特性 |
SerializableData (SampleData(Object)) | bytea | 4 bytes加上實際的二進制字串,變長的二進制字串 |
Java Types | PostgreSQL Types | 特性 |
.gif | bytea | 4 bytes加上實際的二進制字串,變長的二進制字串 |
.jpg | ||
.png | ||
.mp3 |
Java Types | PostgreSQL Types | 特性 |
java.util.Calendar | date | 4 bytes,只用於日期 |
time | 8 bytes,只用於一日內時間 | |
timestamp | 8 bytes,包括日期和時間 |
Java Types | 自己產生時間 | 存入PostgreSQL資料庫的對應型別 |
java.util.Date | T | 需要轉譯 |
java.util.Calendar | T | 需要轉譯 |
java.sql.Date | F | date |
java.sql.Time | F | time |
java.sql.Timestamp | F | timestamp |