• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            在本文中,我們將學(xué)習(xí)如何編寫(xiě)簡(jiǎn)單的 Perl 程序來(lái)提取或操作 IBM® DB2® Universal Database™(DB2 UDB)中存儲(chǔ)的數(shù)據(jù)。我們將從一個(gè)簡(jiǎn)單的任務(wù)入手:從數(shù)據(jù)庫(kù)中選擇一行數(shù)據(jù)放入一個(gè) Perl 程序中;接著逐步介紹一些高級(jí)主題,包括處理大對(duì)象和調(diào)用存儲(chǔ)過(guò)程。

            簡(jiǎn)介

            Perl(Practical Extraction and Report Language)是一種功能強(qiáng)大而又非常簡(jiǎn)單易用的編程語(yǔ)言,在很多操作系統(tǒng)上都可以使用。Perl 是免費(fèi)的。我們可以(以源代碼或二進(jìn)制的格式)下載這個(gè)語(yǔ)言,并可以免費(fèi)地使用它。

            Perl 日漸成為一種廣受歡迎的語(yǔ)言。它包含了 C 編程語(yǔ)言的特性,以及 UNIX® 中的一些命令,例如 awksed。Perl 是一種解釋語(yǔ)言,可以在單獨(dú)的應(yīng)用程序中使用,也可以與 Apache 一起來(lái)構(gòu)建 Web 應(yīng)用程序。

            我們可以使用 Perl 快速操作來(lái)自文件或 RDBMS 的大型數(shù)據(jù)集。DBI 是在 Perl 腳本中連接 RDBMS 的標(biāo)準(zhǔn),它是在 1994 年開(kāi)始引入的。在 http://dbi.perl.org/ 站點(diǎn)上可以找到 DBI 驅(qū)動(dòng)程序的源代碼及其文檔。

            IBM 在 1992 年為 Perl 開(kāi)發(fā)了 DB2 的驅(qū)動(dòng)程序,并隨著 DBI 規(guī)范的發(fā)展周期性地對(duì)其進(jìn)行更新。這個(gè)驅(qū)動(dòng)程序的最新版本(在撰寫(xiě)本文時(shí))是 0.78。在 http://www.ibm.com/software/data/db2/perl/ 上可以找到主要的 DBD::DB2(這是 Perl 語(yǔ)言中采用的命名機(jī)制)驅(qū)動(dòng)程序信息。

            本文將展示如何編寫(xiě)簡(jiǎn)單的 Perl 程序來(lái)提取或操作 DB2 UDB 中存儲(chǔ)的數(shù)據(jù)。我們將從一個(gè)簡(jiǎn)單的任務(wù)入手:從數(shù)據(jù)庫(kù)中選擇一行數(shù)據(jù)放入一個(gè) Perl 程序中;接著逐步介紹一些高級(jí)主題,包括處理大對(duì)象和調(diào)用存儲(chǔ)過(guò)程。

            開(kāi)始

            圖 1 展示了 Perl 環(huán)境如何與數(shù)據(jù)庫(kù)環(huán)境進(jìn)行交互:


            圖 1. Perl 環(huán)境
            Perl 環(huán)境

            正如可以從這個(gè)圖中看出的,Perl 程序使用了一個(gè)標(biāo)準(zhǔn)的 API 來(lái)與 DBI(Perl 的數(shù)據(jù)庫(kù)接口模塊)進(jìn)行通信。Perl DBI 模塊只能支持動(dòng)態(tài) SQL。它定義了一組方法、變量和約定來(lái)提供一個(gè)與實(shí)際使用的數(shù)據(jù)庫(kù)獨(dú)立的一致數(shù)據(jù)庫(kù)接口。DBI 為 API 提供了一個(gè)一致的接口,它可以適用于程序員想使用的任何數(shù)據(jù)庫(kù)。DBD::DB2 是一個(gè) Perl 模塊,當(dāng)與 DBI 一起使用時(shí),它就可以讓 Perl 與 DB2 UDB 進(jìn)行通信。

            因此,為了運(yùn)行訪(fǎng)問(wèn) DB2 數(shù)據(jù)庫(kù)的 Perl 腳本,需要在系統(tǒng)上安裝以下組件:

            • Perl 語(yǔ)言環(huán)境
            • DBI 驅(qū)動(dòng)程序(可以用于任何 RDBMS)
            • DBD::DB2 驅(qū)動(dòng)程序
            • DB2 Runtime Client
            • C 編譯器
            • DB2 數(shù)據(jù)庫(kù)服務(wù)器的連接信息

            http://www.ibm.com/software/db2/perl/ 的 Web 站點(diǎn)上可以看到所有的安裝配置指南。

            連接到 DB2 數(shù)據(jù)庫(kù)上

            為了讓 Perl 程序訪(fǎng)問(wèn) DB2 數(shù)據(jù)庫(kù),需要建立到數(shù)據(jù)庫(kù)的連接。為了讓 Perl 加載 DBI 模塊,需要在 Perl DB2 應(yīng)用程序中包含下面的內(nèi)容:

            use DBI;

            當(dāng)使用 DBI->connect 語(yǔ)句(語(yǔ)法如下)來(lái)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)句柄 時(shí),DBI 模塊會(huì)自動(dòng)加載 DBD::DB2 驅(qū)動(dòng)程序。


            清單 1. 創(chuàng)建數(shù)據(jù)庫(kù)句柄
            
                        use DBI;
                        $dbh = DBI->connect (“dbi:DB2:dbalias", $UserId, $password);
                        

            其中:

            $dbh —— 表示 connect 語(yǔ)句所返回的數(shù)據(jù)庫(kù)句柄
            dbalias —— 表示分類(lèi)進(jìn) DB2 數(shù)據(jù)庫(kù)目錄中的 DB2 別名
            $userID —— 表示用來(lái)連接數(shù)據(jù)庫(kù)的用戶(hù) ID
            $password —— 表示這個(gè)用戶(hù) ID 的密碼

            清單 2 展示了一個(gè)簡(jiǎn)單的 Perl 程序,它建立到數(shù)據(jù)庫(kù) SAMPLE 的連接,并返回今天的日期。這個(gè)程序執(zhí)行一條動(dòng)態(tài)生成的 DB2 SQL 語(yǔ)句,從數(shù)據(jù)庫(kù)中獲取 CURRENT DATE。它使用 DBI -> bind_col 方法將數(shù)據(jù)庫(kù)中的值傳遞到一個(gè)本地變量中,稍后我們就會(huì)討論這個(gè)問(wèn)題。


            清單 2. 連接到數(shù)據(jù)庫(kù)上并執(zhí)行語(yǔ)句
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use strict;
                        # Open a connection
                        my $dbh = DBI->connect("dbi:DB2:sample", “DB2ADMIN", “db2admin“, {RaiseError => 1});
                        # use VALUES to retrieve value from special register
                        my $stmt = "Values CURRENT DATE";
                        my $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        # associate variables with output columns...
                        my $col1;
                        $sth->bind_col(1,\$col1);
                        while ($sth->fetch) { print "Today is: $col1\n"; }
                        $sth->finish();
                        $dbh->disconnect();
                        

            錯(cuò)誤處理 —— SQLCODE 和 SQLSTATE

            為了返回與某個(gè) Perl DBI 數(shù)據(jù)庫(kù)句柄或語(yǔ)句句柄相關(guān)的 SQLSTATE,可以調(diào)用 state 方法。例如,要返回與數(shù)據(jù)庫(kù)句柄 $dbhandle 相關(guān)的 SQLSTATE ,可以在應(yīng)用程序中使用下面的 Perl 語(yǔ)句:

            my $sqlstate = $dbhandle->state;

            為了返回與某個(gè) Perl DBI 數(shù)據(jù)庫(kù)句柄或語(yǔ)句句柄相關(guān)的 SQLCODE,可以調(diào)用 err 方法。例如,要返回與數(shù)據(jù)庫(kù)句柄 $dbhandle 相關(guān)的 SQLCODE,可以在應(yīng)用程序中使用下面的 Perl 語(yǔ)句:

            my $sqlcode = $dbhandle->err;

            errstr 方法返回與某個(gè) Perl DBI 數(shù)據(jù)庫(kù)句柄或語(yǔ)句句柄相關(guān)的 SQLCODE 的消息。我推薦使用這個(gè)方法,因?yàn)檫@個(gè)方法可以給出有關(guān) SQL 語(yǔ)句失敗的更多信息。

            清單 3 中的例子展示了這個(gè)方法的用法:


            清單 3. 返回錯(cuò)誤消息的 errstr 方法
            
                        $dbh = DBI->connect("dbi:DB2:sample",“USERID",“password") or
                        die “Can't connect to sample database: $DBI::errstr";
                        $sth = $dbh->prepare(“SQL statement“) or   die "Cannot prepare: " $dbh->errstr;
                        $sth->>execute() or   die "Cannot execute: " $sth->errstr;
                        

            現(xiàn)在讓我們進(jìn)一步看一下第一個(gè)實(shí)驗(yàn)。它展示了一個(gè) Perl 程序,這個(gè)程序使用作為參數(shù)傳入的用戶(hù) ID 和密碼來(lái)連接數(shù)據(jù)庫(kù) SAMPLE。當(dāng)傳遞了有效的 ID 和密碼時(shí),它會(huì)返回一條消息說(shuō)明連接成功了。下面是 lab1.pl 的代碼:


            清單 4. lab1.pl
            
                        #!/usr/local/bin/perl –w
                        use DBI;
                        $db2user = $ARGV[0];
                        $pasw = $ARGV[1];
                        # Open a connection
                        $dbh = DBI->connect("dbi:DB2:sample", $db2user, $pasw)  or
                        “Can't connect to sample database: $DBI::errstr";
                        print "Connection is successful !!\n";
                        

            圖 2 給出了使用有效身份驗(yàn)證和無(wú)效身份驗(yàn)證來(lái)執(zhí)行這個(gè)程序的結(jié)果:


            圖 2. 執(zhí)行 lab1.pl
            執(zhí)行 lab1.pl

             

            執(zhí)行 SQL 語(yǔ)句

            下面讓我們來(lái)編寫(xiě)一個(gè)程序,在數(shù)據(jù)庫(kù) SAMPLE 中創(chuàng)建一個(gè)表 PT_ADDR_BOOK。要執(zhí)行在編寫(xiě)應(yīng)用程序時(shí)就已經(jīng)知道的 SQL 語(yǔ)句,可以使用 $dbh->do 方法。這個(gè)方法的語(yǔ)法如下所示:

            my $cnt = $dbh->do(SQL statement);

            其中 $cnt 是這條 SQL 語(yǔ)句所影響的行數(shù)。

            使用這個(gè)方法,我們的程序創(chuàng)建了一個(gè) DB2 表,如清單 5 所示:


            清單 5. 用來(lái)創(chuàng)建 DB2 表的程序
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die “Can't connect to sample database: $DBI::errstr";
                        $rcount = $dbh->do (“CREATE TABLE PT_addr_book(name char(30),
                        phone char(10))");
                        print “Returns: $rcount\n";
                        

            可以使用相同的 do 方法向 PT_addr_book 表中插入幾行數(shù)據(jù)。請(qǐng)注意,所插入行的值在編寫(xiě)這個(gè)程序時(shí)都是已知的,因此可以硬編碼在代碼中。


            清單 6. 使用 do 方法插入幾行數(shù)據(jù)
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die "Can't connect to sample database: $DBI::errstr";
                        $rcount = $dbh-> do ("Insert into PT_ADDR_BOOK values
                        ('Gregory Whales','9142712020'),
                        ('Robert Moses', 2127652345')");
                        print "Returns: $rcount \n";
                        

            正如從這個(gè)例子中可以看到的,這條 SQL 語(yǔ)句會(huì)影響兩行數(shù)據(jù)。通過(guò)在 DB2 CLP 中對(duì)這個(gè)表運(yùn)行 SELECT 語(yǔ)句,可以確定有兩行數(shù)據(jù)已經(jīng)插入了這個(gè)表中。


            清單 7. test_do_exs.pl
            
                        $perl test_do_exs.pl
                        Returns : 2
                        $db2 “select * from PT_ADDR_BOOK"
                        NAME                               PHONE
                        ------------------------------ ----------
                        Gregory Whales                 9142712020
                        Robert Moses                   2127652345
                        2 record(s) selected.
                        

            下面讓我們從 下載 一節(jié)中實(shí)驗(yàn) 2 的練習(xí)開(kāi)始,編寫(xiě)并執(zhí)行一個(gè)簡(jiǎn)單的 Perl 程序來(lái)更新 PR_ADDR_BOOK 表。

            INSERT、UPDATE 和 DELETE 語(yǔ)句 —— 沒(méi)有占位符

            執(zhí)行一條在編寫(xiě)應(yīng)用程序時(shí)還未確定的 SQL 語(yǔ)句(動(dòng)態(tài) SQL)需要使用一種不同的技術(shù),可以使用 $dbh->prepare 方法來(lái)實(shí)現(xiàn)。動(dòng)態(tài) SQL 可以通過(guò)在程序執(zhí)行過(guò)程中自己修改列、表和謂詞(操作)的能力來(lái)實(shí)現(xiàn)。動(dòng)態(tài) SQL 需要由 UDB 優(yōu)化器來(lái)準(zhǔn)備 執(zhí)行,目的是為這條語(yǔ)句創(chuàng)建一個(gè)訪(fǎng)問(wèn)計(jì)劃。如果動(dòng)態(tài) SQL 沒(méi)有參數(shù)標(biāo)記(占位符),它就可以在這個(gè)步驟之后立即執(zhí)行。清單 8 給出了 $dbh->prepare$sth->execute 方法的語(yǔ)法,可以在 Perl 程序中用來(lái)執(zhí)行沒(méi)有占位符的嵌入式 SQL 語(yǔ)句:


            清單 8. 動(dòng)態(tài) SQL 的準(zhǔn)備和執(zhí)行
            
                        $stmt = “SQL Statement without placeholder“;
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        

            請(qǐng)注意,$dbh->prepare 方法的結(jié)果是 SQL 語(yǔ)句句柄。

            清單 9 中給出的 Perl 程序展示了如何使用這些方法將一行數(shù)據(jù)插入到 PT_ADDR_BOOK 表中:


            清單 9. 插入一行數(shù)據(jù)
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die “Can't connect to sample database: $DBI::errstr";
                        $stmt = "INSERT INTO PT_addr_book values ('JOHN SMITH','9145556677')“;
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        print "We inserted row into addr_book\n";
                        $sth->finish();
                        

            具有參數(shù)標(biāo)記的 SQL 語(yǔ)句

            現(xiàn)在讓我們來(lái)看一下如何執(zhí)行在編寫(xiě)應(yīng)用程序時(shí)還不確定并且具有參數(shù)標(biāo)記(即占位符)的 SQL 語(yǔ)句 —— 即真正的動(dòng)態(tài) SQL 語(yǔ)句。請(qǐng)注意,我們推薦使用這種 SQL 語(yǔ)句,因?yàn)樗鼈兙哂行阅芎桶踩苑矫娴膬?yōu)點(diǎn)。從性能的角度來(lái)看,動(dòng)態(tài) SQL 語(yǔ)句只需要準(zhǔn)備一次就可以執(zhí)行多次,可以重用相同的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)計(jì)劃。從安全性的角度來(lái)看,占位符可以確保只有一個(gè)值可以插入到這條語(yǔ)句中,從而可以避免出現(xiàn) SQL 語(yǔ)句錯(cuò)誤。

            為了讓 Perl 程序?qū)?dòng)態(tài) SQL 語(yǔ)句轉(zhuǎn)換成可執(zhí)行的格式,需要首先使用 prepare 方法,然后使用 bind_param 方法來(lái)綁定參數(shù)。只有這樣才可以執(zhí)行這條語(yǔ)句。要綁定每個(gè)參數(shù),需要指定參數(shù)標(biāo)記的個(gè)數(shù),以及包含這些參數(shù)標(biāo)記值的本地 Perl 變量的名字。清單 10 給出了讓 Perl 程序執(zhí)行動(dòng)態(tài) SQL 語(yǔ)句所使用的方法的語(yǔ)法:


            清單 10. 動(dòng)態(tài) SQL 的方法
            
                        $stmt = “SQL Statement with parameter marker“;
                        $sth = $dbh->prepare($stmt);
                        $sth->bind_param(1,$parm,\% attr);
                        $sth->execute();
                        

            清單 11 展示了對(duì)表 PT_ADDR_BOOK 執(zhí)行 INSERT 操作的方法。現(xiàn)在,所插入列的值不再是在 SQL 語(yǔ)句中硬編碼的了,而是使用參數(shù)標(biāo)記動(dòng)態(tài)傳遞給這條語(yǔ)句的;這些參數(shù)標(biāo)記已經(jīng)使用 $sth->bind_param 方法與這條語(yǔ)句進(jìn)行了綁定。只有完成這些設(shè)置之后,才開(kāi)始執(zhí)行這條語(yǔ)句。


            清單 11. 對(duì)表 PT_ADDR_BOOK 執(zhí)行 INSERT 操作
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die “Can't connect to sample database :DBI::errstr";
                        $name ="STEVE BROWN";
                        $phone = "7184358769";
                        $stmt = "INSERT INTO PT_addr_book values (?,?)";
                        $sth = $dbh->prepare($stmt);
                        $sth->bind_param(1,$name);
                        $sth->bind_param(2,$phone);
                        $sth->execute();
                        print "We inserted row into addr_book\n";
                        $sth->finish();
                        

            從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù) —— 單個(gè)結(jié)果

            為了將數(shù)據(jù)庫(kù)中的值放到 Perl 程序中使用,需要按照下面的步驟執(zhí)行:

            1. 準(zhǔn)備 SELECT 語(yǔ)句。
            2. 執(zhí)行所準(zhǔn)備的語(yǔ)句。
            3. 使用 $sth->bind_col 方法把某列的值(或函數(shù))關(guān)聯(lián)到一個(gè)本地 Perl 變量上。
            4. 使用 $sth->fetch 方法將一個(gè)值取到本地變量中。

            下面的偽碼展示了如何從數(shù)據(jù)庫(kù)中檢索單個(gè)值:


            清單 12. 從數(shù)據(jù)庫(kù)中檢索單個(gè)值
            
                        $stmt = “SQL SELECT Statement to be executed“;
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        $result = $sth->bind_col(col, \variable [, \%attr ]);
                        while ($sth->fetch){
                        process result of the fetch;
                        }
                        

            下面這個(gè)例子展示了如何為一個(gè)聚合函數(shù) max 從 EMPLOYEE 表中檢索 salary 的值:


            清單 13. 為聚合函數(shù)檢索值
            
                        #!/usr/local/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die “Can't connect to sample database: $DBI::errstr";
                        $stmt = "SELECT max(salary) from EMPLOYEE";
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        #associate variable with output columns...
                        $sth->bind_col(1,\$max_sal);
                        while ($sth->fetch) {
                        print "The biggest salary is: $max_sal\n";
                        }
                        

            下面是執(zhí)行這個(gè) Perl 程序后的結(jié)果:


            清單 14. 聚合結(jié)果值
            
                        $perl test_return_value.pl
                        The biggest salary is: 52750.00
                        

            從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù) —— 多個(gè)結(jié)果

            從數(shù)據(jù)庫(kù)中返回一個(gè)結(jié)果集(即多個(gè)結(jié)果)到 Perl 程序中的技術(shù)與前面所采用的技術(shù)非常類(lèi)似。在準(zhǔn)備并執(zhí)行返回多個(gè)結(jié)果的 SQL 語(yǔ)句并將返回值(列)綁定到本地變量上之后,可能需要使用 $sth->fetch 方法來(lái)檢索這些值。為了展示這個(gè)方法是如何工作的,下面讓我們從 PT_ADDR_BOOK 表中檢索出 phone 和 name 列的內(nèi)容。清單 15 給出了使用一個(gè)循環(huán)來(lái)使用 $sth_fetch 方法的用法:


            清單 15. 從數(shù)據(jù)庫(kù)中檢索多個(gè)值
            
                        $stmt = "SELECT name, phone from PT_ADDR_BOOK";
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        #associate variables with output columns...
                        $sth->bind_col(1,\$name);
                        $sth->bind_col(2,\$phone);
                        print "NAME                          PHONE      \n";
                        print "-------------------------     -----------\n";
                        while ($sth->fetch) {
                        print $name ;
                        print $phone; print "\n";              }
                        print "DONE \n";
                        $sth->finish();
                        

            執(zhí)行這段代碼的結(jié)果如下:


            清單 16. 從數(shù)據(jù)庫(kù)中檢索多個(gè)值
            
                        C:\Dev_POT\PERL\Labs>perl multi.pl
                        NAME                          PHONE
                        -------------------------     -----------
                        JOHN SMITH               9145556677
                        STEVE BROWN          7184358769
                        DONE
                        

            也可以使用 $sth->fetchrow 方法從結(jié)果集中檢索數(shù)據(jù)。$sth ->fetch 方法會(huì)將每個(gè)值作為單獨(dú)一項(xiàng)返回,而 $sth ->fetchrow() 方法則將一行作為一個(gè)數(shù)組返回,每列的值都是該數(shù)組中的一個(gè)元素。

            可以使用 fetchrow 方法編寫(xiě)功能相同的 Perl 程序,如下所示:


            清單 17. 從數(shù)據(jù)庫(kù)中檢索多個(gè)值
            
                        $stmt = "SELECT name, phone from PT_ADDR_BOOK";
                        $sth = $dbh->prepare($stmt);
                        $sth->execute();
                        print "NAME                          PHONE      \n";
                        print "-------------------------     -----------\n";
                        while (($name, $phone) = $sth->fetchrow())
                        { print "$name  $phone\n"; }
                        

            我們可以從 實(shí)驗(yàn) 3 開(kāi)始編寫(xiě)并執(zhí)行一個(gè) Perl 程序,它可以創(chuàng)建一個(gè) DB2 表,向該表中插入一些數(shù)據(jù),并返回插入該表中的行數(shù)。

            調(diào)用存儲(chǔ)過(guò)程

            下面讓我們來(lái)創(chuàng)建一個(gè)多個(gè)步驟的場(chǎng)景,從而詳細(xì)了解一下如何從 Perl 程序中調(diào)用 DB2 的存儲(chǔ)過(guò)程。首先,創(chuàng)建一個(gè)簡(jiǎn)單的存儲(chǔ)過(guò)程 SP_GET_LOC,它從表 ORG 中返回某個(gè)給定部門(mén)的位置(步驟 1)。


            清單 18. 步驟 1:創(chuàng)建存儲(chǔ)過(guò)程
            
                        create procedure sp_get_loc (in deptin int, out loc varchar(13))
                        begin
                        select location into loc from org where deptnumb = deptin;
                        end  @
                        

            請(qǐng)注意,這個(gè)存儲(chǔ)過(guò)程有一個(gè)輸入?yún)?shù)和一個(gè)輸出參數(shù)。當(dāng)我們?cè)?DB2 的命令行處理器(CLP)中運(yùn)行這個(gè)過(guò)程時(shí),它對(duì)部門(mén) 10 會(huì)返回位置 NEW YORK。


            清單 19. 步驟 2:運(yùn)行存儲(chǔ)過(guò)程
            
                        $db2 "call sp_get_loc(10,?)"
                        Value of output parameters
                        --------------------------
                        Parameter Name  : LOC
                        Parameter Value : New York
                        Return Status = 0
                        

            下面讓我們來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的 Perl 程序來(lái)調(diào)用存儲(chǔ)過(guò)程 SP_GET_LOC(步驟 3,請(qǐng)參看 清單 20)。我們的動(dòng)態(tài) SQL 語(yǔ)句實(shí)際上與在 DB2 CLP 中執(zhí)行的語(yǔ)句相同,形式為 SP_GET_LOC(?,?),不過(guò)在 CLP 中是傳遞硬編碼的 10(部門(mén)編號(hào)),在動(dòng)態(tài) SQL 語(yǔ)句中將使用一個(gè)參數(shù)標(biāo)記。采用這種方法,就可以對(duì) ORG 表的部門(mén)編號(hào)列的任何值查詢(xún)位置了。

            在構(gòu)造 SQL 語(yǔ)句之后,剩下的步驟就與其他具有參數(shù)標(biāo)記的動(dòng)態(tài)語(yǔ)句完全相同了。可以使用 $sth = $dbh->prepare 方法進(jìn)行準(zhǔn)備。使用 $sth->bind_param 方法將部門(mén)編號(hào)綁定為輸入?yún)?shù),使用 $sth->bind_param_inout 方法將返回的位置綁定為輸出參數(shù),然后再執(zhí)行動(dòng)態(tài) SQL 語(yǔ)句。

            該程序如下:


            清單 20. 步驟 3:調(diào)用存儲(chǔ)過(guò)程
            
                        #!/usr/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        $dbh = DBI->connect("dbi:DB2:sample","","") or
                        die "Can't connect to sample database: $DBI::errstr";
                        # Prepare our call statement
                        $sth = $dbh->prepare( "CALL SP_GET_LOC(?,?)" );
                        # Bind input parameter for department number
                        $sth->bind_param(1, 10);
                        # Bind output parameter - location
                        $sth->bind_param_inout (2, \$location, 13,     db2_param_type=>SQL_PARAM_OUTPUT});
                        # Call the stored procedure
                        $sth->execute();
                        printf("Stored procedure returned location: %s\n", $location);
                        $sth->finish();
                        $dbh->disconnect;
                        

            如果執(zhí)行這個(gè)程序,就會(huì)看到給定部門(mén)(本例中為 10)的 LOCATION:


            清單 21. 步驟 4:執(zhí)行調(diào)用 DB2 存儲(chǔ)過(guò)程的 Perl 程序
            
                        $perl test_call_sp.pl
                        Stored Procedure returned location: New York
                        

            大對(duì)象的操作

            使用 Perl 來(lái)處理文件比使用其他更復(fù)雜的語(yǔ)言(例如 C 或 Java®)都要簡(jiǎn)單。下面我們就會(huì)看到如何將數(shù)據(jù)直接從文件中導(dǎo)入 DB2 的大對(duì)象數(shù)據(jù)(LOB)列中。插入大對(duì)象數(shù)據(jù)的最有效的方法是,將這個(gè)文件直接綁定到 DB2 表中一個(gè)與 LOB 類(lèi)型的列相關(guān)聯(lián)的輸入?yún)?shù)上。Perl 驅(qū)動(dòng)程序可以直接從文件中讀取數(shù)據(jù),并將數(shù)據(jù)傳遞給數(shù)據(jù)庫(kù)服務(wù)器。要將一個(gè)文件綁定到某個(gè)輸入 LOB 參數(shù)上,可以在執(zhí)行 INSERT 操作過(guò)程中使用 bind_param 方法來(lái)指定 { db2_file => 1} 參數(shù)屬性。

            在我們的數(shù)據(jù)庫(kù)模式 POT 下面有一個(gè)表 MAP。這個(gè)表有一個(gè) picture 列,它被聲明成 BLOB 類(lèi)型的,用來(lái)存放某個(gè)地區(qū)的圖像。下面是創(chuàng)建該表所使用的 DDL:


            清單 22. 創(chuàng)建 MAP 表使用的 DDL
            
                        create table POT.MAPS
                        ( map_id           INT,
                        map_name     VARCHAR(13),
                        area                 INT ,
                        photo_format CHAR(3),
                        picture            BLOB) ;
                        

            另外,我們還有一個(gè)文件 pearcson.jpg,其中包含了 Pearson Airport 的地圖。


            圖 3. 示例地圖
            示例地圖

            現(xiàn)在讓我們來(lái)編寫(xiě)一個(gè)程序,向表 POT.MAP 中插入一行數(shù)據(jù),即將 JPG 文件的圖像插入到 PICTURE 中。首先,需要構(gòu)造一個(gè)具有 5 個(gè)參數(shù)標(biāo)記的動(dòng)態(tài) SQL 語(yǔ)句。然后,需要對(duì)這條語(yǔ)句進(jìn)行準(zhǔn)備。在將參數(shù)綁定到準(zhǔn)備好的語(yǔ)句上之前,需要指定包含要插入的圖像的文件名,并將其賦給一個(gè)本地 Perl 變量($picture_file)。現(xiàn)在可以將所有參數(shù)全部綁定到需要插入到 MAP 表中的值上。請(qǐng)注意,我們?yōu)樽詈笠粋€(gè)參數(shù)指定了 db2_file =>1 屬性。最后一個(gè)步驟是執(zhí)行這條 INSERT 語(yǔ)句。這個(gè)程序的代碼如下:


            清單 23. 插入 LOB
            
                        #!/usr/bin/perl -w
                        use DBI;
                        use DBD::DB2::Constants;
                        %conattr = (   AutoCommit             => 1,
                        # Turn Autocommit On
                        db2_info_applname  => 'Maps Module', );
                        # Identify this appl
                        $dbh = DBI->connect("dbi:DB2:sample","", "",\%conattr) or die "$DBI::errstr";
                        $dbh->do("SET CURRENT SCHEMA POT");
                        $sql = "INSERT INTO MAPS(map_id, map_name, area, photo_format, picture)
                        VALUES(?,?,?,?,?)";
                        $sth = $dbh->prepare($sql);
                        $picture_file = "pearson.jpg";           # File containing our picture
                        $sth->bind_param(1, 100);                # map_id
                        $sth->bind_param(2, "Pearson airport");  # map_name
                        $sth->bind_param(3, 416);                # area
                        $sth->bind_param(4, "JPG");              # photo_format
                        $sth->bind_param(5, $picture_file, {db2_file => 1});
                        $rows_affected = $sth->execute();
                        printf("%d rows affected", $rows_affected);
                        $sth->finish();
                        $dbh->disconnect;
                        

            從數(shù)據(jù)庫(kù)中讀取 LOB 數(shù)據(jù)

            可以使用標(biāo)準(zhǔn)的 fetch 方法來(lái)檢索 LOB 數(shù)據(jù),例如 fetchrow_arrayfetchrow_arrayref。DBI 讓我們可以使用 LongReadLen 連接屬性來(lái)設(shè)置每次 fetch 可以檢索的最大字節(jié)數(shù)。對(duì)于 LOB 列來(lái)說(shuō),缺省值為 32,700 個(gè)字節(jié)。要實(shí)現(xiàn)這種功能,需要執(zhí)行以下步驟:

            1. 構(gòu)造 SQL 語(yǔ)句從 MAP 表中選擇 picture 列的數(shù)據(jù)。
            2. 準(zhǔn)備 SQL 語(yǔ)句。
            3. 為保存所檢索到的圖像使用的文件分配一個(gè)名字。
            4. 打開(kāi)該文件。
            5. 執(zhí)行這條 SQL 語(yǔ)句。
            6. 使用 fetch 方法將結(jié)果取到文件中。

            下面是展示如何從數(shù)據(jù)庫(kù)中檢索 LOB 數(shù)據(jù)的代碼:


            清單 24. 從數(shù)據(jù)庫(kù)中讀取 LOB 數(shù)據(jù)
            
                        #!/usr/bin/perl
                        use DBI;
                        use DBD::DB2::Constants;
                        %conattr =
                        (
                        AutoCommit             => 1,
                        # Turn Autocommit On
                        db2_info_applname  => 'Maps Module',
                        # Identify this appl
                        LongReadLen           => 80000
                        # Don't retrieve LOBs
                        );
                        # Connect to our database
                        $dbh = DBI->connect("dbi:DB2:sample","", "",\%conattr) or
                        die "$DBI::errstr";
                        # Set the current schema to 'POT'
                        $dbh->do("SET CURRENT SCHEMA POT");
                        $sql = "SELECT picture FROM maps WHERE map_name ='Pearson airport'";
                        # Prepare the statement
                        $sth = $dbh->prepare($sql);
                        # Open output file
                        $out_file = "mypic.jpg";
                        open(OUTPUT, ">$out_file") or die "Cannot open $out_file because $!";
                        binmode OUTPUT;
                        $sth->execute;
                        @row = $sth->fetchrow;
                        print OUTPUT $row[0];
                        @row = "";
                        close(OUTPUT);
                        print “Picture in the file $out_file\n";
                        $sth->finish();
                        $dbh->disconnect;
                        

            在運(yùn)行這個(gè)程序之后,圖像就保存到 mypic.jpg 文件中了。


            清單 25. 從數(shù)據(jù)庫(kù)中讀取 LOB 數(shù)據(jù)
            
                        $perl test_lobread.pl
                        Picture in the file mypic.jpg
                        

            請(qǐng)使用 實(shí)驗(yàn) 4 中的練習(xí)來(lái)編寫(xiě)并執(zhí)行一個(gè) Perl 程序,它從一個(gè)表中檢索出二進(jìn)制大對(duì)象,并將其保存到一個(gè)文件中。

            結(jié)束語(yǔ)

            本文是為那些具有關(guān)系數(shù)據(jù)庫(kù)經(jīng)驗(yàn)并且希望學(xué)習(xí)如何編寫(xiě) Perl 程序來(lái)訪(fǎng)問(wèn) DB2 數(shù)據(jù)庫(kù)的 Perl 程序員編寫(xiě)的。在本文中,我們已經(jīng)學(xué)習(xí)了如何連接數(shù)據(jù)庫(kù),如何通過(guò) INSERT、UPDATE 和 DELETE 語(yǔ)句來(lái)操作數(shù)據(jù)庫(kù)的內(nèi)容。還學(xué)習(xí)了如何從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),并介紹了一些高級(jí)主題,包括調(diào)用存儲(chǔ)過(guò)程和操作大數(shù)據(jù)對(duì)象(LOB 和 BLOB)。現(xiàn)在我們應(yīng)該已經(jīng)準(zhǔn)備好使用自己剛掌握的 Perl DB2 編程技巧來(lái)開(kāi)發(fā)自己的程序了。

            原文鏈接:http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/dm-0512greenstein/index.html

            久久精品嫩草影院| 国产AⅤ精品一区二区三区久久| 久久青草国产精品一区| 亚洲va国产va天堂va久久| 一极黄色视频久久网站| 久久久久久国产精品免费免费| 久久精品免费观看| 久久午夜电影网| 久久国产精品久久精品国产| 国内精品久久人妻互换| 国产精品久久毛片完整版| 香蕉久久一区二区不卡无毒影院 | 要久久爱在线免费观看| 欧美精品一区二区久久| 日本精品久久久久久久久免费| 国产日韩欧美久久| 无码人妻少妇久久中文字幕| 亚洲国产成人久久一区久久| 日韩精品久久久久久久电影| 久久久SS麻豆欧美国产日韩| 日产精品久久久久久久| www.久久99| 久久AAAA片一区二区| 亚洲欧美精品一区久久中文字幕| 亚洲精品97久久中文字幕无码| 久久乐国产综合亚洲精品| 久久男人Av资源网站无码软件| 国产精品久久波多野结衣| 国产L精品国产亚洲区久久| 亚洲AV伊人久久青青草原| 亚洲va久久久噜噜噜久久| 青青草国产精品久久久久| 久久综合视频网站| 日韩精品久久久肉伦网站| 91精品国产高清久久久久久91 | 久久久久一本毛久久久| 亚洲&#228;v永久无码精品天堂久久| 久久亚洲熟女cc98cm| 久久精品国产一区二区三区日韩| 久久精品国产一区二区三区| 亚洲成色www久久网站夜月|