程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> IBM InfoSphere Federation Server V9.7 中 VARCHAR2 數據類型及相關語義的支持

IBM InfoSphere Federation Server V9.7 中 VARCHAR2 數據類型及相關語義的支持

編輯:DB2教程

簡介

本文介紹了 InfoSphere Federation Server V9.7 中對 VARCHAR2 數據類型及相關語義的支持。從 DB2 V9.5 開始,DB2 開始增加了一個新的數據類型 VARCHAR2。該功能作為 DB2 增強對其他數據庫 SQL 尤其是 PL/SQL 支持的一部分,有效降低了客戶應用程序從 Oracle 向 DB2 移植的難度。而 InfoSphere Federation Server 作為 DB2 數據庫的延伸,也需要增加對 VRACHAR2 數據類型以及其相關語義的支持。特別當聯邦數據庫支持 VARCHAR2 時,根據遠程數據源是否支持 VARCHAR2,InfoSphere Federation Server 如何保證正確的語義處理。

本文將首先介紹什麼是 VARCHAR2 數據類型。然後介紹如何在 InfoSphere Federation server 中使用 VARCHAR2 數據類型。最後根據遠程數據庫和聯邦數據庫支持該特性與否組合生成四種配置,以及每種配置下對字符串操作的影響。

1. VARCHAR2 數據類型

VARCHAR2 最初是由 Oracle 開發的一種類似工業標准中 VARCHAR 的數據類型。但 VARCHAR2 在以下方面與標准 VARCHAR 存在差異:。

在 VARCHAR2 語義中,空字符串被存儲為 NULL,而標准語義中允許空字符串;

在 VARCHAR2 語義中,變長字符串比較基於 non blank-padding 算法;而在標准語義中,變長字符串比較基於 blank-padding 算法;

不超過 255B 的常量字符串被存儲為 CHAR,超過 254B 的常量字符串被存儲為 VARCHAR2;VARCHAR2 的最大長度是 32672B;

標量函數的返回值如果是長度為 0 的字符串,那麼該返回值為 NULL。

由 VARCHAR2 的這種定義所引出的相關字符串語義,我們稱為 Oracle 字符串語義或者 VARCHAR2 語義。

DB2 增加了一個注冊變量 DB2_COMPATIBILITY_VECTOR。當該變量設置為 0x20 時,創建的數據庫遵循 VARCHAR2 語義。

例如:

清單 1. 創建遵循 VARCHAR2 語義的數據庫

 db2set DB2_COMPATIBILITY_VECTOR=20; 
 db2 terminate; 
 db2stop; 
 db2start; 
 db2 create db SAMPLE1; 

這裡創建的數據庫 SAMPLE1 將遵循 VARCHAR2 語義。

清單 2. 創建不遵循 VARCHAR2 語義的數據庫

 db2set DB2_COMPATIBILITY_VECTOR=; 
 db2 terminate; 
 db2stop; 
 db2start; 
 db2 create db SAMPLE2; 

這裡創建的數據庫 SAMPLE2 不遵循 VARCHAR2 語義。

可以通過命令”db2 get db cfg”來檢查相應數據庫是否支持該語義。

清單 3. 檢查數據庫是否支持 VARCHAR2 語義

 db2 => get db cfg for SAMPLE1; 
 
    Database Configuration for Database SAMPLE1 
 
 Database configuration release level          = 0x0d00 
 Database release level                 = 0x0d00 
 
 Database territory                   = US 
 Database code page                   = 1208 
 Database code set                    = UTF-8 
 Database country/region code              = 1 
 Database collating sequence               = SYSTEM_819 
 Alternate collating sequence       (ALT_COLLATE) = 
 Number compatibility                  = OFF 
 Varchar2 compatibility               = ON 
 Date compatibility                   = OFF 
 Database page size                   = 4096 
…… 

2. Federation Server 中如何使用 VARCHAR2 數據類型

InfoSphere Federation Server v9.7 支持兩種模式。缺省模式是不支持 VARCHAR2 語義的;另外一種是 VARCHAR2 兼容模式,支持 VARCHAR2 語義。後一種模式的打開是通過在創建聯邦數據庫之前設置注冊變量 DB2_COMPATIBILITY_VECTOR 為 0x20( 該變量的缺省值是 0)。

需要指出的一點是,在 VARCHAR2 兼容模式下,DB2 及 Federation Server 支持 VARCHAR2 數據類型。VARCHAR2 和 VARCHAR 是同義詞。而且在 catalog 中最終存儲的數據類型是 VARCHAR。也就是說在 VARCHAR2 兼容模式下,VARCHAR 與 VARCHAR2 具有相同的語義。而在 catalog 中,VARCHAR2 類型並不存在。

InfoSphere Federation Server v9.7 為支持 VARCHAR2 語義,引入了兩個新的 server options:

VARCHAR2_COMPAT:表明遠程數據源是否支持 VARCHAR2 語義。對於 Oracle 數據源,該屬性缺省為’ Y ’;對於其他數據源缺省為’ N ’;對於兼容 VARCHAR2 的 DB2 LUW 數據源,需要用戶設置該屬性為’ Y ’;對於通過 ODBC 或 JDBC 包裝器來訪問的兼容 VARCHAR2 的數據源,也需要用戶設置該屬性為’ Y'

NO_EMPTY_STRING:既是 server option,也是 column option。表明遠程數據源或者遠程 column 是否有空字符串。缺省值是’ N ’。當聯邦數據庫支持 VARCHAR2 語義,而遠程數據源不支持 VARCHAR2 語義時,如果能判斷遠程數據源或者其某個列中不存在空字符串,設置該屬性為’ Y ’,可以避免從空字符串到 NULL 的轉換,從而提高性能

在開始使用 Federation 數據庫前,我們需要做下面准備工作:

1) 打開 Federation 功能

db2 update dbm cfe using federated yes;

2)創建本地聯邦數據庫(創建支持 VARCHAR2 語義的聯邦數據庫,請參見上文)

db2 create db sample1 using codeset UTF-8 
 territory US authentication clIEnt;

3)連接到本地數據庫

db2 connect to sample1;

4) 創建需要連接數據源的 Wrapper, Server 和 User Mapping

例如:連接 Oracle 數據源

清單 4. 連接 Oracle 數據源

 create wrapper net8; 
 create server "server1" type Oracle version 11.0 wrapper " net8" 
 authorization "test" password "test" options(node 'ora11g', passWord 'y'); 
 create user mapping for user server "server1" options 
 ( remote_authid 'test', remote_passWord 'test' ); 

5) 創建 Nickname

例如:Oracle 上存在一個統計員工信息的表 EMP,通過下面的語句創建 Nickname ”EMP_LOCAL”

create nickname emp_local for server1."test"."emp";

下面給出如何設置及修改上述 server option 的例子:

例如:為遠端不兼容 VARCHAR2 的 DB2 LUW 數據源創建 Server,顯示地指定 Server options VARCHAR2_COMPAT, NO_EMPTY_STRING。

create server S type db2/cs version 9.7 wrapper W authorization "authid" passWord "pwd“ 
options (dbname 'DBNAME', VARCHAR2_COMPAT ‘ N ’ , NO_EMPTY_STRING ‘ Y ’ );

可以通過 Alter 語句修改 NO_EMPTY_STRING 的值。

alter server S options (set NO_EMPTY_STRING ‘ N ’ );

3. VARCHAR2 相關的 Federation Server 的四種配置

根據遠程數據源和本地聯邦數據庫是否支持 VARCHAR2 語義,Federation server 有四種以下不同的配置:

a) 不支持 VARCHAR2 語義的 Federation Server 連接一個不支持 VARCHAR2 語義的遠程數據源;

b) 不支持 VARCHAR2 語義的 Federation Server 連接一個支持 VARCHAR2 語義的遠程數據源;

c) 支持 VARCHAR2 語義的 Federation Server 連接一個不支持 VARCHAR2 語義的遠程數據源;

d) 支持 VARCHAR2 語義的 Federation Server 連接一個支持 VARCHAR2 語義的遠程數據源;

圖 1. InfoSphere Federation Server v9.7 四種配置
IBM InfoSphere Federation Server V9.7 中 VARCHAR2 數據類型及相關語義的支持

目前,支持 VARCHAR2 語義的遠程數據源有 Oracle 數據庫以及支持 VARCHAR2 語義的 DB2 LUW。其余的數據源缺省地被認為不支持 VARCHAR2 語義。

a) 和 b) 這兩種配置在 InfoSphere Federation Server v9.7 之前的版本中已經支持,例如 InfoSphere Federation Server V9.5 中已經支持 Oracle 數據源。而 InfoSphere Federation Server v9.7 中將配置 b) 擴展到了支持 VARCHAR2 語義的 DB2 LUW。

c) 和 d) 是 InfoSphere Federation Server v9.7 中新支持的兩種配置。要支持這兩種配置,Federation Server 需要在創建聯邦數據庫之前設置”DB2_COMPATIBILITY_VECTOR = 0x20”,這樣生成的聯邦數據庫將支持 VARCHAR2 語義。

對於 c) 配置情形,需要設置以下 server option 屬性:

VARCHAR2_COMPAT = ‘ N ’

NO_EMPTY_STRING = ‘ Y ’ ( 可選 )

例如:

清單 5. 配置 c) 需要的 server options 設置

create server "server1" type informix version 11.0 wrapper "wrapper1" 
 authorization "test" passWord "test" options(varchar2_compat 'n', 
 node 'inf11', dbname 'inf11db', passWord 'y'); 
 
create server "server1" type mssqlserver version 2005 wrapper "wrapper1" 
 authorization "test" passWord "test" options(varchar2_compat 'n', 
 no_empty_string = ‘ y ’ node 'mssql2005', dbname 'mssql2005db', passWord 'y'); 

對於 d) 配置情形,需要設置

VARCHAR2_COMPAT = ‘ Y ’

例如:

清單 6. 配置 d) 需要的 server options 設置

create server "server1" type Oracle version 11.0 wrapper "wrapper1" authorization "test" 
password "test" options(varchar2_compat 'y', node 'ora11g', passWord 'y'); 

下面我們將基於以下字符串操作討論 Federation Server 在不同配置下的表現:

聯邦 VARCHAR 字符串的比較;

聯邦空字符串和 NULL 值

聯邦基於字符串的函數;

3.1 聯邦 VARCHAR 字符串的比較操作

比較操作包括基本謂詞,group by, order by, sorting 等操作。

表 1 給出了四種配置下針對 VARCHAR 字符串比較操作的下推情況:

表 1. VARCHAR 字符串比較操作下推情況

  不支持 VARCHAR2 語義的聯邦數據庫 支持 VARCHAR2 語義的聯邦數據庫 不支持 VARCHAR2 語義的遠程數據源 下推 (a) 不下推 (c) 支持 VARCHAR2 語義的遠程數據源(即 Oracle 或者支持 VARCHAR2 語義的 DB2 LUW) 不下推(對基本謂詞和 IN 操作進行補償下推) (b) 下推 (d)

配置 a),聯邦數據庫和遠程數據源在 VARVCHAR 比較時均使用 blank-padding 算法。一般情形下,VARCHAR 比較操作將會被下推到遠程數據源。

配置 b),聯邦數據庫使用 blank-padding 算法,遠程數據源則使用 non blank-padding 算法。這種情況下,VARCHAR 比較操作將對基本謂詞和 IN 操作帶補償的下推到遠程數據源。

配置 c),聯邦數據庫使用 non blank-padding 算法,而遠程數據源使用 blank-padding 算法。比較操作不會下推。

配置 d),聯邦數據庫和遠程數據源均使用 non blank-padding 算法。比較操作將被下推。

下面是一個 blank-padding 及 non blank-padding 算法的例子:

在 blank-padding 算法中:’ abc ’ = ‘ abc ‘ => true

在 non blank-padding 算法中:’ abc ’ = ‘ abc ‘ => false

例如:

遠端數據庫存在如下一個員工表

create table emp(id int, name varchar(10))

其中包含如下兩條紀錄

insert into emp values(1,'jim')

insert into emp values(2,'jim ')

假設我們在聯邦數據庫中已經建立了表”emp”對應的 Nickname “emp_local”( 具體操作請參見上文 )

1)如果遠端數據庫為 Oracle, VARCHAR 比較操作使用 non blank-padding 算法 .

當通過客戶端直接查找姓名為“JIM”的員工時將只返回第二條紀錄。結果如下:

清單 7.Oracle 中的 VARCHAR 比較操作結果

 select * from emp where name='Jim '; 
 
 ID            NAME 
 ------------------------ ---------- 
 +2.00000000000000E+000 Jim 
 
 1 record(s) selected. 

如果使用聯邦數據庫工作

配置 b) 下 VARCHAR 比較操作將帶補償的下推到遠程數據源(例子中的比較操作 name='Jim '將通過 RPAD 進行補償:RPAD(A0."NAME" , 10, ' ')=RPAD('Jim ', 10, ' ')),從而保證比較操作 name= ’ Jim ‘將得到與聯邦數據庫支持的 blank-padding 算法相同的結果。結果如下:

清單 8. 聯邦數據庫配置 b) 中的 VARCHAR 比較操作結果

 select * from emp_local where name='Jim '; 
 
 ID            NAME 
 ------------------------ ---------- 
 +1.00000000000000E+000 Jim 
 +2.00000000000000E+000 Jim 
 
 2 record(s) selected. 

配置 d) 下 VARCHAR 比較操作將會下推到遠程數據源,比較操作 name='Jim '將下推到 Oracle 數據源使用 non blank-padding 算法。結果如下:

清單 9. 聯邦數據庫配置 d) 中的 VARCHAR 比較操作結果

 select * from emp_local where name='Jim '; 
 
 ID            NAME 
 ------------------------ ---------- 
 +2.00000000000000E+000 Jim 
 
 1 record(s) selected. 

通過比較可以發現,如果遠端數據源是 Oracle,配置 d) 表現出與 Oracle 客戶端一致的行為。

2) 如果遠端數據庫為 Informix, VARCHAR 比較操作使用 blank-padding 算法 .

當通過客戶端直接查找姓名為“JIM”的員工將獲得所有兩條紀錄。結果如下:

清單 10.Informax 中的 VARCHAR 比較操作結果

 select * from emp where name='Jim ' 
 
 id     name 
 ----------- -------------------- 
     1 Jim 
     2 Jim 
 
 2 record(s) selected. 

如果使用聯邦數據庫工作:

配置 a) 下 VARCHAR 比較操作將會下推到遠程數據源,上例中的比較操作 name='Jim '將下推到 Informix 數據源使用 blank-padding 算法。結果如下:

清單 11. 聯邦數據庫配置 a) 中的 VARCHAR 比較操作結果

 select * from emp_local where name='Jim ' 
 
 ID     NAME 
 ----------- ---------- 
     1 Jim 
     2 Jim 
 
 2 record(s) selected. 

配置 c) 下 VARCHAR 比較操作將不會下推,上例中的比較操作 name='Jim '將使用聯邦數據庫支持的 non blank-padding 算法。結果如下:

清單 12. 聯邦數據庫配置 c) 中的 VARCHAR 比較操作結果

 select * from emp_local where name='Jim ' 
 
 ID     NAME 
 ----------- ---------- 
     2 Jim 
 
 1 record(s) selected. 

通過比較可以發現,如果遠端數據源是 Informix,配置 a) 表現出與 Informix 客戶端一致的行為。

例外,

(1) VARCHAR FOR BIT DATA 比較繼續按照帶 IDENTITY 的 blank-padding 算法進行。

(2) Catalog 表中字符串列也按照帶 IDENTITY 的 blank-padding 算法進行,並不考慮數據庫的 code page。

3.2 空字符串和 NULL

支持 VARCHAR2 語義的數據庫會將空字符串存儲為 NULL,即數據庫中不存在空字符串。

表 2 給出了四種配置下針對空字符串的處理:

表 2. 空字符串處理

  不支持 VARCHAR2 語義的聯邦數據庫 支持 VARCHAR2 語義的聯邦數據庫 不支持 VARCHAR2 語義的遠程數據源 與 v97 之前的版本一樣 (a) 不下推 (c) 支持 VARCHAR2 語義的遠程數據源(即 Oracle 或者支持 VARCHAR2 語義的 DB2 LUW) 與 v97 之前的版本一樣 (b) 下推 (d)

配置 a),聯邦數據庫和遠程數據源都支持空字符串,相關操作會下推。

配置 b),聯邦數據庫支持空字符串,而遠程數據源不支持空字符串。如果遠程數據源接收到空字符串,則遠程數據源將其轉換為 NULL 存儲;如果空字符串插入到非 NULL 的列,那麼數據源將報錯。

配置 c),聯邦數據庫不支持空字符串,遠程數據源支持空字符串。只有當能夠保證聯邦數據庫語義和數據一致性的前提下,涉及到空字符串的操作才可以被下推

配置 d),聯邦數據庫和遠程數據源都支持空字符串。由於在聯邦數據庫和遠程數據源中執行結果一致,所以比較操作和涉及到空字符串的操作將會被下推

例如:

遠端數據庫存在如下一個部門表:

create table dep(id int, depname char(10) not null ,employ varchar(10))

現在需要插入如下兩條紀錄

insert into dep values(1,'','Ben') 
insert into dep values (2,'IT','')

1)如果數據源支持 VARCHAR2 語義,如 Oracle,通過 Oracle 客戶端直接操作時,第一條紀錄插入時將報錯,第二條紀錄將成功插入。

清單 13.Oracle 中插入 NULL 的結果

 insert into dep(id,depname,employ) values(1,'','Ben'); 
 DB21034E The command was processed as an SQL statement because it was not a 
 valid Command Line Processor command. During SQL processing it returned: 
 SQL0407N Assignment of a NULL value to a NOT NULL column "NET8 object: 
 Unknown" is not allowed. SQLSTATE=23502 
 
 insert into dep(id,depname,employ) values (2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select * from dep; 
 
 ID              DEPNAME  EMPLOY 
 ------------------------ ---------- ---------- 
 +2.00000000000000E+000 IT      - 
 
 1 record(s) selected. 

使用聯邦數據庫操作時,假設我們在聯邦數據庫中已經建立了表”dep”對應的 Nickname “dep_local”:

配置 b) 下,如果遠程數據源接收到空字符串,則遠程數據源將其轉換為 NULL 存儲;如果空字符串插入到非 NULL 的列,那麼數據源將報錯。上例執行結果如下:

清單 14. 聯邦數據庫配置 b) 下插入 NULL 的結果

 insert into dep_local(id,depname,employ) values(1,'','Ben'); 
 DB21034E The command was processed as an SQL statement because it was not a 
 valid Command Line Processor command. During SQL processing it returned: 
 SQL0407N Assignment of a NULL value to a NOT NULL column "NET8 object: 
 Unknown" is not allowed. SQLSTATE=23502 
 
 insert into dep_local(id,depname,employ) values (2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select * from dep_local; 
 
 ID            DEPNAME  EMPLOY 
 ------------------------ ---------- ---------- 
 +2.00000000000000E+000 IT     - 
 
 1 record(s) selected. 

這裡需要特別說明的是對於 CHAR 類型列的操作。根據 DB2 的語義,將空字符串插到 CHAR 類型的列中時,空字符串在發送到遠程數據源之前會被 blank-padded,即根據 CHAR 類型的長度將空字符串轉為該長度的空格,遠程數據源接收到的將是空格。上例中如果一次性插入兩條紀錄:

insert into dep_local(id,depname,employ) values(1,'','Ben'),(2,'IT','');

第一條紀錄中的空字串在發送到遠程數據源前會被擴展,遠程數據源將接收到 10 個空格而不是空字符串。執行結果如下:

清單 15. 聯邦數據庫配置 b) 下向 CHAR 類型的列插入多行 NULL 的結果

 insert into dep_local(id,depname,employ) values(1,'','Ben'),(2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select id,depname,length(depname) as length from dep_local; 
 
 ID                 DEPNAME     LENGTH       
 ------------------------    ----------   -----------     
 +1.00000000000000E+000              10          
 +2.00000000000000E+000     IT        10          
 
 2 record(s) selected. 

另一方面對於單行插入或者更新操作,當聯邦數據庫發現操作是基於 nickname 時,會改變 DB2 的語義,直接將空字符串映射為 NULL,而不進行 blank-pad 操作。因此在例子中我們對 CHAR 類型非空列”depname”單行插入空串時,數據源返回如下錯誤信息:

清單 16. 聯邦數據庫配置 b) 下插入 CHAR 類型列插入單行 NULL 的結果

 SQL0407N Assignment of a NULL value to a NOT NULL column "NET8 object: 
 Unknown" is not allowed. SQLSTATE=23502” 

配置 d) 下,涉及到空字符串的操作將會被下推數據源 Oracle,結果如下:

清單 17. 聯邦數據庫配置 d) 下插入 NULL 的結果

 insert into dep_local values(1,'','Ben'); 
 DB21034E The command was processed as an SQL statement because it was not a 
 valid Command Line Processor command. During SQL processing it returned: 
 SQL0407N Assignment of a NULL value to a NOT NULL column "NET8 object: 
 Unknown" is not allowed. SQLSTATE=23502 
 
 insert into dep_local values (2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select * from dep_local; 
 
 ID              DEPNAME   EMPLOY 
 ------------------------ ---------- ---------- 
 +2.00000000000000E+000 IT      - 
 
 1 record(s) selected. 

2)如果數據源不支持 VARCHAR2 語義,如 Informix,通過 Informix 客戶端直接操作時,兩條紀錄都可以成功插入;

清單 18.Informix 中插入 NULL 的結果

 insert into dep values(1,'','Ben') 
 DB20000I The SQL command completed successfully. 
 
 insert into dep values (2,'IT','') 
 DB20000I The SQL command completed successfully. 
 
 select * from dep 
 
 id      depname         employ 
 ----------- -------------------- -------------------- 
     1               Ben 
     2  IT            
 
 2 record(s) selected. 

使用聯邦數據庫操作時,假設我們在聯邦數據庫中已經建立了表”dep”對應的 Nickname “dep_local”:

配置 a) 下,相關操作會下推,結果如下:

清單 19. 聯邦數據庫配置 a) 下插入 NULL 的結果

 insert into dep_local values(1,'','Ben'); 
 DB20000I The SQL command completed successfully. 
 
 insert into dep_local values (2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select * from dep_local; 
 
 ID      DEPNAME   EMPLOY 
 ----------- ---------- ---------- 
     1         Ben 
     2  IT 
 
 2 record(s) selected. 

配置 c) 下,由於 Federation 數據庫支持 VARCHAR2 語義空字符串將被存儲為 NULL,結果如下:

清單 20. 聯邦數據庫配置 c) 下插入 NULL 的結果

 insert into dep_local values(1,'','Ben'); 
 DB21034E The command was processed as an SQL statement because it was not a 
 valid Command Line Processor command. During SQL processing it returned: 
 SQL0407N Assignment of a NULL value to a NOT NULL column "dep.depname" is not 
 allowed. SQLSTATE=23502 
 
 insert into dep_local values (2,'IT',''); 
 DB20000I The SQL command completed successfully. 
 
 select * from dep_local; 
 
 ID      DEPNAME   EMPLOY 
 ----------- ---------- ---------- 
     2  IT     - 
 
 1 record(s) selected. 

通過比較可以發現,如果遠端數據源是 Informix,配置 a) 表現出與 Informix 客戶端一致的行為。

3.3 scalar 函數

一般情況下,如果 Scalar 字符串函數的參數是 NULL,則返回值通常也是 NULL。而在 VARCHAR2 語義中,長度為 0 的 CHAR 或者 VARCHAR 字符串也被認為是 NULL 值。例如,UPPER(),LOWER(),LENGTH(),CHARACTER_LENGTH() 等。

而且,如果某 scalar 字符串函數在不支持 VARCHAR2 語義的模式下返回空字符串,則該函數在 VARCHAR2 模式下將返回 NULL 值。例如,TRIM(),SUBSTR() 等。

VARCHAR2 語義給某些基於字符串的 SYSIBM 函數帶來的語義變化,如 CONCAT()。CONCAT (c1,null) 在不支持 VARACHAR2 語義的 DB2 中的返回值是 NULL,在 Oracle 或者支持 VARCHAR2 語義的 DB2 中的返回值是 c1. 類似的函數有 INSERT(), REPLACE() 等。

上面提到的 scalar 字符串函數在配置 (a) 和 (d) 中將被下推,而在配置 (b) 和 (c) 中不會下推。表 3 給出了四種配置下針對上述 scalar 函數的處理。

表 3. scalar 函數的處理

  不支持 VARCHAR2 語義的聯邦數據庫 支持 VARCHAR2 語義的聯邦數據庫 不支持 VARCHAR2 語義的遠程數據源 下推 (a) 不下推 (c) 支持 VARCHAR2 語義的遠程數據源 不下推 (b) 下推 (d)

例如:

遠端數據庫存在如下一個經理表:

create table manager(id int,department char(20),manager varchar(10)) 

現在需要插入如下兩條紀錄

insert into manager values(1,'IT','') 
insert into manager values(1,'Others',null)

1)如果數據源支持 VARCHAR2 語義,如 Oracle,通過 Oracle 客戶端直接操作將得到如下結果:

清單 21. Oracle 中使用函數 upper 返回所有記錄中大寫的 manager 名字的結果

 select id,department,upper(manager) as manager from manager; 
 
 ID              DEPARTMENT       MANAGER 
 ------------------------ -------------------- ---------- 
 +1.00000000000000E+000 IT            - 
 +2.00000000000000E+000 Others         - 
 
 2 record(s) selected. 

清單 22. Oracle 中使用函數 substr 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager; 
 
 ID              DEPARTMENT 
 ------------------------ ---------- 
 +1.00000000000000E+000 - 
 +2.00000000000000E+000 - 
 
 2 record(s) selected. 

清單 23. Oracle 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager; 
 
 ID              MANAGER 
 ------------------------ ------------- 
 +1.00000000000000E+000 Mr 
 +2.00000000000000E+000 Mr 
 
 2 record(s) selected. 

使用聯邦數據庫操作時,假設我們在聯邦數據庫中已經建立了表”manager”對應的 Nickname “manager_local”

配置 b) 下,scalar 字符串函數不會被下推。上例中的結果如下:

清單 24. 聯邦數據庫配置 b) 中使用函數 UPPER 返回所有記錄中 manager 的名字的結果

 select id,department,upper(manager) as manager from manager_local; 
 
 ID                  DEPARTMENT        MANAGER   
 ------------------------     --------------------  ----------  
 +1.00000000000000E+000      IT             -       
 +2.00000000000000E+000      Others           -       
 
 2 record(s) selected. 

清單 25. 聯邦數據庫配置 b) 中使用函數 SUBSTR 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager_local; 
 
 ID              DEPARTMENT 
 ------------------------ ---------- 
 +1.00000000000000E+000 
 +2.00000000000000E+000 
 
 2 record(s) selected. 

清單 26. 聯邦數據庫配置 b) 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager_local; 
 
 ID              MANAGER 
 ------------------------ ------------- 
 +1.00000000000000E+000 - 
 +2.00000000000000E+000 - 
 
 2 record(s) selected. 

配置 d) 下 , scalar 字符串函數會被下推。上例中的結果如下:

清單 27. 聯邦數據庫配置 d) 中使用函數 UPPER 返回所有記錄中 manager 的名字的結果

 select id,department,upper(manager) as manager from manager_local; 
 
 ID                  DEPARTMENT        MANAGER   
 ------------------------     --------------------  ----------  
 +1.00000000000000E+000      IT             -       
 +2.00000000000000E+000      Others           -       
 
 2 record(s) selected. 

清單 28. 聯邦數據庫配置 d) 中使用函數 SUBSTR 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager_local; 
 
 ID              DEPARTMENT 
 ------------------------ ---------- 
 +1.00000000000000E+000 - 
 +2.00000000000000E+000 - 
 
 2 record(s) selected. 

清單 29. 聯邦數據庫配置 b) 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager_local; 
 
 ID              MANAGER 
 ------------------------ ------------- 
 +1.00000000000000E+000 Mr 
 +2.00000000000000E+000 Mr 
 
 2 record(s) selected. 

通過比較可以發現,如果遠端數據源是 Oracle,配置 d) 表現出與 Oracle 客戶端一致的行為。

2)如果數據源不支持 VARCHAR2 語義,如 Informix,通過 Informix 客戶端直接操作將得到如下結果:

清單 30. Informix 中使用函數 UPPER 返回所有記錄中 manager 的名字的結果

 select id,department,upper(manager) as manager from manager 
 
 id      department                   manager 
 ----------- ---------------------------------------- -------------------- 
     1  IT 
     2  Others                      - 
 
 2 record(s) selected. 

清單 31. Informix 中使用函數 SUBSTR 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager 
 
 id     department 
 ----------- ---------- 
     1 
     2 
 
 2 record(s) selected. 

清單 32. Informix 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager 
 
 id      manager 
 ----------- -------------------------- 
     1  Mr 
     2  - 
 
 2 record(s) selected. 

配置 a) 下 ,scalar 字符串函數會被下推。上例中的結果如下:

清單 33. 聯邦數據庫配置 a) 中使用函數 UPPER 返回所有記錄中 manager 的名字的結果

 select id,department,upper(manager) as manager from manager_local; 
 
 ID     DEPARTMENT        MANAGER 
 ----------- -------------------- ---------- 
     1 IT 
     2 Others          - 
 
 2 record(s) selected. 

清單 34. 聯邦數據庫配置 a) 中使用函數 SUBSTR 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager_local; 
 
 ID     DEPARTMENT 
 ----------- ---------- 
     1 
     2 
 
 2 record(s) selected. 

清單 35. 聯邦數據庫配置 a) 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager_local; 
 
 ID      MANAGER 
 ----------- ------------- 
     1  Mr 
     2  - 
 
 2 record(s) selected. 

配置 c) 下 , scalar 字符串函數不會被下推。上例中的結果如下:

清單 36. 聯邦數據庫配置 c) 中使用函數 UPPER 返回所有記錄中 manager 的名字的結果

 select id,department,upper(manager) as manager from manager_local; 
 
 ID     DEPARTMENT        MANAGER 
 ----------- -------------------- ---------- 
     1 IT             - 
     2 Others          - 
 
 2 record(s) selected. 

清單 37. 聯邦數據庫配置 c) 中使用函數 SUBSTR 返回所有記錄中 departname 從第一個字符起 0 長的子字串的結果

 select id,substr(department,1,0) as department from manager_local; 
 
 ID      DEPARTMENT 
 ----------- ---------- 
     1  - 
     2  - 
 
 2 record(s) selected. 

清單 38. 聯邦數據庫配置 c) 中使用函數 CONCAT 使返回記錄中 manager 姓名前加上’ Mr ’的結果

 select id,concat('Mr',manager) as manager from manager_local; 
 
 ID      MANAGER 
 ----------- ------------- 
     1  Mr 
     2  Mr 
 
 2 record(s) selected. 

通過比較可以發現,如果遠端數據源是 Informix,配置 a) 表現出與 Informix 客戶端一致的行為。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved