DB2下數(shù)據(jù)轉(zhuǎn)移任務(wù)操作實(shí)例
使用 DB2 LOAD 實(shí)用程序的 FROM CURSOR 選項(xiàng)簡(jiǎn)化 DB2 for Linux, UNIX, and Windows的數(shù)據(jù)轉(zhuǎn)移過(guò)程。本文介紹 LOAD FROM CURSOR 特性并提供兩個(gè)接口 Command Line Processor 和 ADMIN_CMD 存儲(chǔ)過(guò)程的使用示例。
簡(jiǎn)介
典型的 DB2 數(shù)據(jù)轉(zhuǎn)移任務(wù)涉及三個(gè)步驟:
◆把數(shù)據(jù)以二進(jìn)制或文本格式從源數(shù)據(jù)庫(kù)導(dǎo)出到一個(gè)臨時(shí)數(shù)據(jù)交換文件
◆在系統(tǒng)之間轉(zhuǎn)移生成的文件
◆把數(shù)據(jù)從文件導(dǎo)入或裝載到目標(biāo)數(shù)據(jù)庫(kù)中
在數(shù)據(jù)量很大的情況下,使用 EXPORT 實(shí)用程序生成數(shù)據(jù)交換文件常常要花費(fèi)很長(zhǎng)時(shí)間。另外,在把數(shù)據(jù)移入和移出數(shù)據(jù)庫(kù)時(shí),必須考慮不同的數(shù)據(jù)庫(kù)編碼頁(yè)和操作系統(tǒng)。
可以使用 LOAD 實(shí)用程序的 FROM CURSOR 選項(xiàng)避免這些問(wèn)題。當(dāng)指定 FROM CURSOR 選項(xiàng)時(shí),LOAD 實(shí)用程序直接把一個(gè) SQL 查詢的結(jié)果集作為數(shù)據(jù)裝載操作的來(lái)源,這樣就不需要生成臨時(shí)數(shù)據(jù)交換文件。因此,LOAD FROM CURSOR 是在不同的表空間或數(shù)據(jù)庫(kù)之間快速輕松地轉(zhuǎn)移數(shù)據(jù)的方法??梢栽诿钚猩蠄?zhí)行 LOAD FROM CURSOR,也可以通過(guò)使用 DB2 的 ADMIN_CMD 存儲(chǔ)過(guò)程在應(yīng)用程序或存儲(chǔ)過(guò)程中執(zhí)行它。本文介紹 LOAD FROM CURSOR 特性并提供兩個(gè)接口 Command Line Processor (CLP) 和 ADMIN_CMD 存儲(chǔ)過(guò)程的使用示例。
把表轉(zhuǎn)移到另一個(gè)表空間
首先,看看如何把表從一個(gè)表空間轉(zhuǎn)移到另一個(gè)表空間。如果創(chuàng)建表的表空間的頁(yè)面大小不合適,或者應(yīng)該用另一個(gè)緩沖區(qū)池訪問(wèn)表,就可能需要執(zhí)行這種數(shù)據(jù)轉(zhuǎn)移。在 9.1 以前的 DB2 版本中,常常由于達(dá)到表空間的最大大小而在表空間之間轉(zhuǎn)移表。但是,在 DB2 9.1 和更高版本中,這應(yīng)該不再是問(wèn)題了,因?yàn)楸砜臻g大小限制已經(jīng)顯著提高了(前提是使用大表空間,而不是以前使用的常規(guī)表空間)。
這個(gè)示例場(chǎng)景首先創(chuàng)建 DB2 SAMPLE 數(shù)據(jù)庫(kù)。這可以通過(guò)在命令行上調(diào)用 db2sampl 命令來(lái)完成,見(jiàn)清單 1。
清單 1. 創(chuàng)建 SAMPLE 數(shù)據(jù)庫(kù)
C:\>db2sampl |
除了其他表之外,SAMPLE 數(shù)據(jù)庫(kù)包含一個(gè)名為 SALES 的表。在默認(rèn)情況下,在表空間 USERSPACE1 中創(chuàng)建這個(gè)表??梢酝ㄟ^(guò)對(duì) DB2 編目視圖 SYSCAT.TABLES 和 SYSCAT.TABLESPACES 執(zhí)行查詢來(lái)確認(rèn)這一點(diǎn)。
清單 2. 判斷 SALES 表的表空間
C:\>db2 "CONNECT TO SAMPLE" |
除了 USERSPACE1 表空間之外,還有第二個(gè)表空間 IBMDB2SAMPLEREL,它也用于存儲(chǔ)用戶數(shù)據(jù)。在這個(gè)示例場(chǎng)景中,IBMDB2SAMPLEREL 作為轉(zhuǎn)移 SALES 表的目標(biāo)表空間。執(zhí)行 DB2 命令 LIST TABLESPACES,就可以看到一個(gè)數(shù)據(jù)庫(kù)的所有表空間。清單 3 演示具體做法。
清單 3. 列出 SAMPLE 數(shù)據(jù)庫(kù)的所有表空間
C:\>db2 "LIST TABLESPACES" |
在把 SALES 表的內(nèi)容復(fù)制到 IBMDB2SAMPLEREL 表空間之前,必須在目標(biāo)表空間中創(chuàng)建一個(gè)空表,此表的結(jié)構(gòu)應(yīng)該與 SALES 表相同。因?yàn)樵谕粋€(gè)數(shù)據(jù)庫(kù)模式中不可能有兩個(gè)同名的表,所以臨時(shí)用 SALES_TMP 這個(gè)名稱(chēng)創(chuàng)建新的表。通過(guò)在 CREATE TABLE 命令中指定 LIKE 選項(xiàng),創(chuàng)建一個(gè)與現(xiàn)有表結(jié)構(gòu)相同的空表(清單 4)。通過(guò) IN 選項(xiàng)顯式地定義新表 SALES_TMP 的表空間。
清單 4. 創(chuàng)建數(shù)據(jù)轉(zhuǎn)移操作所需的目標(biāo)表 SALES_TMP
C:\>db2 "CREATE TABLE FECHNER.SALES_TMP LIKE FECHNER.SALES IN IBMDB2SAMPLEREL" |
現(xiàn)在,可以執(zhí)行數(shù)據(jù)轉(zhuǎn)移操作了。使用 DECLARE CURSOR 命令定義一個(gè)游標(biāo),它使用 SELECT 語(yǔ)句讀取源表 SALES 的所有數(shù)據(jù)。可以自由選擇游標(biāo)的名稱(chēng),在此示例中使用 C1。然后,在用來(lái)填充目標(biāo)表 SALES_TMP 的 LOAD 命令中引用此游標(biāo)。此示例中的 LOAD 命令把它的消息寫(xiě)到日志文件 load_sales_tmp.msg 中。執(zhí)行的 LOAD 操作包含 NONRECOVERABLE 選項(xiàng)。這意味著在數(shù)據(jù)庫(kù)恢復(fù)的前滾階段無(wú)法重新執(zhí)行這個(gè) LOAD 操作。因此,在執(zhí)行數(shù)據(jù)轉(zhuǎn)移操作之后,應(yīng)該執(zhí)行數(shù)據(jù)庫(kù)備份,至少是表空間備份。LOAD 命令有其他選項(xiàng)可以避免這種情況,但是這些選項(xiàng)超出了本文的范圍。更多信息請(qǐng)參見(jiàn) DB2 Information Center 中對(duì) LOAD 命令的說(shuō)明(參見(jiàn) 參考資料)。
清單 5. 執(zhí)行 LOAD FROM CURSOR 操作把 SALES 表中的所有行復(fù)制到 SALES_TMP 表
C:\>db2 "DECLARE C1 CURSOR FOR SELECT * FROM FECHNER.SALES" |
在把 SALES 表中的所有行成功地復(fù)制到 SALES_TMP 表之后,可以刪除源表(DROP TABLE 語(yǔ)句)。然后,把目標(biāo)表 SALES_TMP 重命名為 SALES(RENAME TABLE 語(yǔ)句)。在使用 RENAME TABLE 時(shí),只能修改表名,而不能修改表的模式名。因此,一定要在正確的模式中創(chuàng)建 SALES_TMP 表。
清單 6. 刪除源表 SALES 并重命名目標(biāo)表 SALES_TMP
C:\>db2 "DROP TABLE FECHNER.SALES" |
再次對(duì) DB2 編目視圖執(zhí)行查詢,可以確認(rèn) SALES 表已經(jīng)從原來(lái)的表空間 USERSPACE1 轉(zhuǎn)移到了新的表空間 IBMDB2SAMPLEREL 中,見(jiàn)清單 7。
清單 7. 確認(rèn)新 SALES 表的表空間
C:\>db2 "SELECT TABLES.TABSCHEMA, TABLES.TABNAME, TBSPACES.TBSPACE FROM SYSCAT.TABLES AS |
#p#
使用別名在另一個(gè)數(shù)據(jù)庫(kù)中創(chuàng)建表拷貝
除了可以在一個(gè)數(shù)據(jù)庫(kù)中的表空間之間轉(zhuǎn)移表之外,還可以在不同的數(shù)據(jù)庫(kù)之間轉(zhuǎn)移表。這意味著:通過(guò)使用 LOAD FROM CURSOR,也可以把表從一個(gè)數(shù)據(jù)庫(kù)轉(zhuǎn)移到另一個(gè)數(shù)據(jù)庫(kù)。這可以通過(guò)兩種方法完成:
方法 1 - 在目標(biāo)數(shù)據(jù)庫(kù)中,使用 DB2 的聯(lián)邦數(shù)據(jù)庫(kù)機(jī)制訪問(wèn)源數(shù)據(jù)庫(kù)。
方法 2 - 使用 LOAD FROM CURSOR 命令的遠(yuǎn)程訪問(wèn)特性。
這兩種方法各有優(yōu)點(diǎn),下面分別討論。
方法1 使用 DB2 的聯(lián)邦數(shù)據(jù)庫(kù)機(jī)制
通過(guò)對(duì)源數(shù)據(jù)庫(kù)執(zhí)行聯(lián)邦訪問(wèn)來(lái)復(fù)制表內(nèi)容。方法 1 要求目標(biāo)數(shù)據(jù)庫(kù)被配置為聯(lián)邦數(shù)據(jù)庫(kù)。因此,對(duì)應(yīng)的 DB2 實(shí)例的 FEDERATED 參數(shù)必須設(shè)置為 YES(UPDATE DBM CFG)。在修改 DBM CFG 參數(shù) FEDERATED 之后,必須重新啟動(dòng) DB2 實(shí)例(db2stop/db2start)。在這個(gè)示例場(chǎng)景中,源和目標(biāo)數(shù)據(jù)庫(kù)在同一個(gè) DB2 實(shí)例中運(yùn)行。創(chuàng)建一個(gè)名為 MYSAMPLE 的空數(shù)據(jù)庫(kù)作為目標(biāo)數(shù)據(jù)庫(kù)。對(duì)于沒(méi)有特殊需求的測(cè)試數(shù)據(jù)庫(kù),可以使用 CREATE DATABASE 命令創(chuàng)建此數(shù)據(jù)庫(kù),不需要其他選項(xiàng)。
清單 8. 在 DBM CFG 中啟用聯(lián)邦數(shù)據(jù)庫(kù)支持并創(chuàng)建空的目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE
C:\>db2 "UPDATE DBM CFG USING FEDERATED YES" |
與前面一樣,必須在目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中創(chuàng)建一個(gè)空表,它的結(jié)構(gòu)與 SAMPLE 數(shù)據(jù)庫(kù)中的 SALES 表相同。因此,應(yīng)該使用 db2look 實(shí)用程序提取源數(shù)據(jù)庫(kù)中 SALES 表的 DDL。
清單 9. 使用 db2look 實(shí)用程序提取源表 SALES 的 DDL
C:\>db2look -d sample -e -z fechner -t sales -o sales.ddl |
db2look 調(diào)用的結(jié)果是 sales.ddl 文件,其中包含 SALES 表的 CREATE TABLE 語(yǔ)句。如果在 SALES 表上定義了約束和/或索引,也會(huì)提取出對(duì)應(yīng)的定義并寫(xiě)到 sales.ddl 文件中。清單 10 顯示這些結(jié)果。
清單 10. db2look 調(diào)用的結(jié)果文件 sales.ddl
-- This CLP file was created using DB2LOOK Version 9.5 |
在對(duì)目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 執(zhí)行 sales.ddl 文件中的語(yǔ)句之前,在文本編輯器中打開(kāi)此文件并對(duì)生成的語(yǔ)句做兩處修改:
在文件的開(kāi)頭,db2look 為源數(shù)據(jù)庫(kù) SAMPLE 生成 CONNECT 語(yǔ)句。因?yàn)橄M麑?duì)目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 執(zhí)行下面的語(yǔ)句,所以要相應(yīng)地修改 CONNECT 語(yǔ)句。
因?yàn)樵谀繕?biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中沒(méi)有用于存儲(chǔ)用戶數(shù)據(jù)的表空間 IBMDB2SAMPLREL,所以要把 CREATE TABLE 語(yǔ)句中的表空間名替換為 USERSPACE1。
清單 11. 結(jié)果文件 sales.ddl 中創(chuàng)建目標(biāo)表所需的修改
CONNECT TO SAMPLE; -> CONNECT TO MYSAMPLE; |
在修改 sales.ddl 文件之后,通過(guò)調(diào)用 DB2 CLP (command line processor) 執(zhí)行此腳本。
清單 12. 在 MYSAMPLE 數(shù)據(jù)庫(kù)中創(chuàng)建目標(biāo)表
C:\>db2 -tf sales.ddl |
到目前為止,只在目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中創(chuàng)建了 SALES 表的空拷貝。準(zhǔn)備數(shù)據(jù)轉(zhuǎn)移操作的下一步是把源數(shù)據(jù)庫(kù) SAMPLE 編目為遠(yuǎn)程數(shù)據(jù)庫(kù)。顯然,這對(duì)于這個(gè)示例場(chǎng)景并不是必需的,因?yàn)樵春湍繕?biāo)數(shù)據(jù)庫(kù)在同一個(gè)服務(wù)器上的同一個(gè) DB2 實(shí)例中運(yùn)行。但是在真實(shí)的環(huán)境中,必須對(duì)運(yùn)行目標(biāo)數(shù)據(jù)庫(kù)的 DB2 實(shí)例執(zhí)行以下 CATALOG 命令,從而允許對(duì)源數(shù)據(jù)庫(kù)進(jìn)行 TCP/IP 訪問(wèn)。
清單 13. 在節(jié)點(diǎn)和數(shù)據(jù)庫(kù)目錄中創(chuàng)建訪問(wèn) SAMPLE 數(shù)據(jù)庫(kù)所需的條目
C:\>db2 "CATALOG TCPIP NODE SRCNODE REMOTE localhost SERVER 50000" |
準(zhǔn)備 LOAD FROM CURSOR 操作的最后一步是配置對(duì)源數(shù)據(jù)庫(kù) SAMPLE 中 SALES 表的聯(lián)邦訪問(wèn)。這需要在目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中創(chuàng)建對(duì)另一個(gè)數(shù)據(jù)庫(kù)執(zhí)行聯(lián)邦訪問(wèn)所需的幾個(gè)特殊對(duì)象:
包裝器
包裝器支持訪問(wèn)外部數(shù)據(jù)源。外部數(shù)據(jù)源可以是另一個(gè) DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng)),比如 Oracle 或 SQL Server,也可以僅僅是 Excel 文件。根據(jù)應(yīng)該訪問(wèn)的數(shù)據(jù)源,需要適當(dāng)?shù)陌b器。這些包裝器包含在單獨(dú)的 IBM product WebSphere® Federation Server 中。如果只希望訪問(wèn) DB2 產(chǎn)品系列(DB2 LUW 或 DB2 z/OS)的另一個(gè)數(shù)據(jù)庫(kù),那么需要 DRDA 包裝器。DB2 LUW 中已經(jīng)包含這個(gè)包裝器,所以在這種情況下不需要 WebSphere Federation Server。通過(guò)在目標(biāo)數(shù)據(jù)庫(kù)中執(zhí)行以下命令,創(chuàng)建 DRDA 包裝器:CREATE WRAPPER DRDA。
服務(wù)器
“服務(wù)器” 這個(gè)詞在這里有點(diǎn)容易引起誤解,因?yàn)檫@實(shí)際上意味著源數(shù)據(jù)庫(kù)扮演(數(shù)據(jù))服務(wù)器的角色。為了在目標(biāo)數(shù)據(jù)庫(kù)中識(shí)別源數(shù)據(jù)庫(kù),要?jiǎng)?chuàng)建一個(gè)服務(wù)器對(duì)象,它指定數(shù)據(jù)源的類(lèi)型 (DB2/UDB VERSION 9.5)、要使用的包裝器 (DRDA) 和訪問(wèn)源數(shù)據(jù)庫(kù)所需的用戶名/密碼組合。使用 DBNAME 選項(xiàng)提供源數(shù)據(jù)庫(kù)本身的名稱(chēng)。用戶名/密碼必須在引號(hào)中指定。為了避免命令行解釋器刪除引號(hào),應(yīng)該加上一個(gè)反斜杠 (\)??梢宰杂蛇x擇服務(wù)器對(duì)象的名稱(chēng)。在這個(gè)示例場(chǎng)景中,使用名稱(chēng) SRCSRV。
用戶映射
對(duì)于希望用前面定義的服務(wù)器對(duì)象訪問(wèn)遠(yuǎn)程數(shù)據(jù)庫(kù)的每個(gè)用戶,都必須創(chuàng)建一個(gè)用戶映射。用戶映射定義本地?cái)?shù)據(jù)庫(kù) (MYSAMPLE) 中的授權(quán) ID 如何映射到遠(yuǎn)程數(shù)據(jù)庫(kù) (SAMPLE) 中的授權(quán) ID。在這個(gè)示例場(chǎng)景中,本地用戶和遠(yuǎn)程用戶是相同的,但是仍然必須定義用戶映射。
別名
別名是源數(shù)據(jù)庫(kù)中的遠(yuǎn)程表的本地別名。指定了別名,就可以在目標(biāo)數(shù)據(jù)庫(kù)中用 SQL 語(yǔ)句查詢遠(yuǎn)程表,就像查詢?nèi)魏伪镜乇硪粯印?/P>
清單 14. 創(chuàng)建聯(lián)邦訪問(wèn)所需的數(shù)據(jù)庫(kù)對(duì)象
C:\>db2 "CONNECT TO MYSAMPLE" |
注意:這里描述的設(shè)置聯(lián)邦訪問(wèn)所需的步驟完全獨(dú)立于 LOAD FROM CURSOR 功能。這意味著這些是為遠(yuǎn)程數(shù)據(jù)庫(kù)中的表創(chuàng)建別名的通用步驟。
配置了對(duì)源數(shù)據(jù)庫(kù)表的聯(lián)邦訪問(wèn)之后,就可以像前面一樣執(zhí)行 LOAD FROM CURSOR 操作。首先,定義一個(gè)游標(biāo),它使用上面創(chuàng)建的別名讀取遠(yuǎn)程表中的所有行。然后,在 LOAD 命令中引用這個(gè)游標(biāo)。
清單 15. 使用別名執(zhí)行遠(yuǎn)程 LOAD FROM CURSOR 操作
C:\>db2 "DECLARE C1 CURSOR FOR SELECT * FROM FECHNER.SRCTAB" |
正如前面提到的,與方法 2 相比,結(jié)合使用 LOAD FROM CURSOR 操作和聯(lián)邦訪問(wèn)需要做的配置工作比較多。但是,聯(lián)邦訪問(wèn)的主要優(yōu)點(diǎn)是可以從非 DB2 數(shù)據(jù)源裝載數(shù)據(jù)。通過(guò)使用聯(lián)邦方式,可以訪問(wèn) Oracle、SQL Server 等數(shù)據(jù)源以及其他許多關(guān)系和非關(guān)系數(shù)據(jù)源,通過(guò)創(chuàng)建別名并執(zhí)行引用別名的 LOAD FROM CURSOR 操作來(lái)復(fù)制內(nèi)容。WebSphere Federation Server 產(chǎn)品提供訪問(wèn)非 DB2 數(shù)據(jù)源所需的包裝器。
#p#
方法2 使用 LOAD FROM CURSOR 命令的遠(yuǎn)程訪問(wèn)特性
既然已經(jīng)了解了使用別名的遠(yuǎn)程 LOAD FROM CURSOR 操作方法,現(xiàn)在看看另一種比較簡(jiǎn)便的方法。為此,首先刪除剛才在目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中的 SALES 表中導(dǎo)入的所有行,見(jiàn)清單 16。
清單 16. 刪除目標(biāo)表中的所有行,以便再次執(zhí)行 LOAD FROM CURSOR 操作
C:\>db2 "CONNECT TO MYSAMPLE" |
對(duì)于第二種方法,不需要配置對(duì)遠(yuǎn)程數(shù)據(jù)庫(kù)的聯(lián)邦訪問(wèn)。只需使用 DATABASE 選項(xiàng)在 DECLARE CURSOR 語(yǔ)句中指定遠(yuǎn)程數(shù)據(jù)庫(kù)。為此,要在本地 DB2 實(shí)例的系統(tǒng)數(shù)據(jù)庫(kù)目錄中對(duì)遠(yuǎn)程數(shù)據(jù)庫(kù)進(jìn)行編目。前面已經(jīng)給出了所需的 CATALOG 命令。另外,在定義游標(biāo)時(shí)要指定遠(yuǎn)程訪問(wèn)所需的用戶名和密碼。LOAD 命令本身保持不變。
清單 17. 在不使用別名的情況下執(zhí)行遠(yuǎn)程 LOAD FROM CURSOR 操作
C:\>db2 "DECLARE C1 CURSOR DATABASE SRCDB USER fechner USING password FOR SELECT * FROM |
從 DB2 9.1 開(kāi)始,可以以這種方式執(zhí)行遠(yuǎn)程 LOAD FROM CURSOR 操作,這種方式基于 DB2 8 中的聯(lián)邦訪問(wèn)方法。這種新方法有兩個(gè)優(yōu)點(diǎn) —— 容易使用且性能好。顯然,新方法非常容易使用。性能比聯(lián)邦方法好是因?yàn)樯婕暗臄?shù)據(jù)傳輸層更少。但是,不應(yīng)該忘記聯(lián)邦方法的優(yōu)點(diǎn),即可以訪問(wèn)非 DB2 數(shù)據(jù)源。
CLP 和 ADMIN_CMD 在 LOAD FROM CURSOR 方面的差異
可以通過(guò)特殊的存儲(chǔ)過(guò)程 ADMIN_CMD 執(zhí)行許多管理命令,從而把管理命令嵌入在應(yīng)用程序代碼中。這也適用于 LOAD FROM CURSOR 操作。存儲(chǔ)過(guò)程 ADMIN_CMD 的使用與應(yīng)用程序代碼的位置無(wú)關(guān),也就是說(shuō),在客戶端代碼(例如 Java 應(yīng)用程序)和服務(wù)器端代碼(例如 SQL/PL 存儲(chǔ)過(guò)程)中都可以使用它。下面的示例在一個(gè)定制的 SQL/PL 存儲(chǔ)過(guò)程中使用 ADMIN_CMD 存儲(chǔ)過(guò)程。create_load_routine.sql 文件包含示例存儲(chǔ)過(guò)程 REMOTE_LOAD_FROM_CURSOR 的 SQL/PL 源代碼。
清單 18. 包含示例存儲(chǔ)過(guò)程的 create_load_routine.sql 文件
CREATE PROCEDURE FECHNER.REMOTE_LOAD_FROM_CURSOR () |
存儲(chǔ)過(guò)程中的第一個(gè)語(yǔ)句是 DELETE,它刪除本地目標(biāo)表 SALES 中現(xiàn)有的行。接下來(lái),用適當(dāng)?shù)?LOAD 命令調(diào)用 ADMIN_CMD,從而執(zhí)行遠(yuǎn)程 LOAD FROM CURSOR 操作。這種方式與從命令行執(zhí)行 LOAD FROM CURSOR 操作的差異如下:
不需要通過(guò)執(zhí)行 DECLARE CURSOR 單獨(dú)定義所需的游標(biāo)。在 LOAD 命令中提供相應(yīng)的 SELECT 語(yǔ)句,就會(huì)隱式地定義游標(biāo)。只有在 ADMIN_CMD 調(diào)用中嵌入 LOAD FROM CURSOR 操作的情況下,這種語(yǔ)法才是有效的,在命令行上是無(wú)效的。
在 LOAD 命令中通過(guò) DATABASE 選項(xiàng)定義遠(yuǎn)程數(shù)據(jù)庫(kù)。不可能指定遠(yuǎn)程訪問(wèn)所需的用戶名/密碼組合。請(qǐng)?jiān)跍y(cè)試存儲(chǔ)過(guò)程時(shí)觀察這一限制的影響。
但是,首先應(yīng)該在目標(biāo)數(shù)據(jù)庫(kù) MYSAMPLE 中創(chuàng)建存儲(chǔ)過(guò)程。
清單 19. 創(chuàng)建示例存儲(chǔ)過(guò)程
C:\>db2 "CONNECT TO MYSAMPLE" |
第一個(gè)測(cè)試調(diào)用失敗,返回消息 SQL30082N Security processing failed with reason "3" ("PASSWORD MISSING"). SQLSTATE=08001。
清單 20. 對(duì)示例存儲(chǔ)過(guò)程的第一次測(cè)試失敗
C:\>db2 "CALL FECHNER.REMOTE_LOAD_FROM_CURSOR" |
這個(gè)錯(cuò)誤消息是由于建立數(shù)據(jù)庫(kù)連接的方式造成的:db2 "CONNECT TO MYSAMPLE"。在執(zhí)行 CONNECT 語(yǔ)句時(shí),沒(méi)有提供用戶名和密碼,因此使用登錄操作系統(tǒng)所用的用戶名建立連接。在這種情況下,DB2 不知道此用戶的密碼。在存儲(chǔ)過(guò)程中執(zhí)行 LOAD FROM CURSOR 操作時(shí),DB2 嘗試用本地用戶的授權(quán) ID 連接遠(yuǎn)程數(shù)據(jù)庫(kù) SAMPLE。但是,由于使用隱式的 CONNECT,DB2 不知道相應(yīng)的密碼,所以遠(yuǎn)程訪問(wèn)失敗。因此,這個(gè)錯(cuò)誤的原因如下:
因?yàn)橥ㄟ^(guò) ADMIN_CMD 執(zhí)行的 LOAD FROM CURSOR 操作不允許指定遠(yuǎn)程訪問(wèn)所用的用戶,所以 LOAD 操作自動(dòng)地用屬于本地?cái)?shù)據(jù)庫(kù)連接的授權(quán) ID 連接遠(yuǎn)程數(shù)據(jù)庫(kù)。
如果本地連接的用戶執(zhí)行隱式的 CONNECT 而沒(méi)有指定密碼,DB2 就不知道他/她的密碼,因此在嘗試連接遠(yuǎn)程數(shù)據(jù)庫(kù)時(shí)沒(méi)有密碼可用。
通過(guò) ADMIN_CMD 執(zhí)行的遠(yuǎn)程 LOAD FROM CURSOR 操作的這一特點(diǎn)(無(wú)法指定遠(yuǎn)程訪問(wèn)所用的用戶)還有一個(gè)影響:當(dāng)前連接本地?cái)?shù)據(jù)庫(kù)的用戶必須用相同的授權(quán) ID 訪問(wèn)遠(yuǎn)程數(shù)據(jù)庫(kù)。在使用聯(lián)邦方法訪問(wèn)遠(yuǎn)程數(shù)據(jù)庫(kù)時(shí),沒(méi)有這一限制,因?yàn)楸仨氁杂脩粲成涞男问蕉x額外的抽象層。
既然找到了錯(cuò)誤的原因,就可以重新連接本地?cái)?shù)據(jù)庫(kù),這一次顯式地指定用戶名和密碼。對(duì)存儲(chǔ)過(guò)程的第二次調(diào)用應(yīng)該會(huì)成功 (Return Status = 0),見(jiàn)清單 21。
清單 21. 對(duì)示例存儲(chǔ)過(guò)程的第二次測(cè)試成功
C:\>db2 "CONNECT TO MYSAMPLE USER fechner" |
結(jié)束語(yǔ)
本文通過(guò)示例場(chǎng)景演示了如何使用 DB2 的 LOAD FROM CURSOR 特性在一個(gè)數(shù)據(jù)庫(kù)中以及不同的數(shù)據(jù)庫(kù)之間快速輕松地復(fù)制數(shù)據(jù)。還解釋了通過(guò) ADMIN_CMD 存儲(chǔ)過(guò)程在應(yīng)用程序代碼中執(zhí)行 LOAD FROM CURSOR 操作時(shí)的特殊問(wèn)題。另外,還講解了如何為另一個(gè)數(shù)據(jù)庫(kù)配置聯(lián)邦訪問(wèn),從而像訪問(wèn)本地表或視圖一樣透明地讀寫(xiě)遠(yuǎn)程數(shù)據(jù)庫(kù)中的表和視圖。
【編輯推薦】