Ⅰ DB2的sql腳本如何定義變數,並賦值使用執行成功有重賞哦,謝謝
用存儲過程啊,給你個簡單的例子
CREATE PROCEDURE SPCARDTRACE
(
IN I_CARDNO VARCHAR(10)
)
-- 存儲過程功能 :
-- 創建人:
-- 創建日期:
-- 參數說明:
-- 01. : I_CARDNO 卡號
-- 02. :
-- 03. :
LANGUAGE SQL
SPECIFIC SPCARDTRACE
DYNAMIC RESULT SETS 1
MODIFIES SQL DATA
BEGIN
DECLARE V_CARDNO VARCHAR(10); --卡號
DECLARE V_EMPNAME VARCHAR(16); --持卡人
DECLARE V_CARDBALANCE DECIMAL(8,2); --卡余額
DECLARE V_HAPPENDATE INT;--統計時間
DECLARE V_MINTIME TIMESTAMP; --最小時間
DECLARE V_MAXTIME TIMESTAMP; --最大時間
DECLARE V_MINMONTH INT ;
DECLARE V_MAXMONTH INT ;
DECLARE V_ISSUECARDDATE TIMESTAMP; --發卡時間
DECLARE V_SUBSIDYMONEY DECIMAL(8,2);--補貼金額
DECLARE V_CONSUMEMONEY DECIMAL(8,2);--沖值金額
DECLARE V_PUTMONEY DECIMAL(8,2);--沖值金額
DECLARE V_OUTMONEY DECIMAL(8,2);--退款金額
DECLARE V_CHANGEMONEY DECIMAL(8,2);--改卡差額
DECLARE V_STRSQL VARCHAR(1000); --SQL
DECLARE CS CURSOR WITH RETURN TO CALLER FOR RETURNTABLE;
INSERT INTO TBCARDTRACE ( CARDNO,EMPNAME,CARDBALANCE,ISSUECARDDATE ,HAPPENDATE,
SUBSIDYMONEY,PUTMONEY,OUTMONEY ,CONSUMEMONEY,CHANGEMONEY )
VALUES (V_CARDNO,V_EMPNAME,V_CARDBALANCE,V_ISSUECARDDATE,V_HAPPENDATE,
V_SUBSIDYMONEY,V_PUTMONEY,V_OUTMONEY,V_CONSUMEMONEY,V_CHANGEMONEY);
END
Ⅱ DB2 SQL5005C 系統錯誤
SQL5005C 系統錯誤。
說明:
訪問配置文件時遇到系統錯誤,很可能是 I/O 錯誤。
無法處理該命令。
用戶響應:
重新提交該命令。
如果此錯誤仍存在,那麼請檢查 db2diag 日誌文件以了解詳細信息,並確保配置
文件可訪問。
Ⅲ DB2用export命令導出表發生錯誤,錯誤提示如下
DB2中所謂的數據移動,包括:1. 數據的導入(Import)2. 數據的導出(Export)3. 數據的裝入(Load)導入和裝入都是利用DB2的相關命令把某種格式的文件中的數據保存到資料庫中的表中導出是指把DB2資料庫的表中的數據保存到某種格式的文件當中去數據移動的作用:如果要在不同的資料庫管理系統之間轉移數據,數據移動通常是最實用的一種方法,因為任何一種資料庫管理系統都支持常用的幾種文件格式,通過這個通用的介面,就很容易實現不同系統間數據的轉移。這三個命令中,Export最簡單,因為從表中向文件轉移數據,通常不會出現錯誤,也不會有非法的數據。在講解命令之前,首先介紹一下文件的格式,用於DB2數據移動的文件格式有四種:1. ASC——非定界ASCII文件,是一個ASCII字元流。數據流中的行由行定界符分隔,而行中的每一列則通過起始和結束位置來定義。例如:10 Head Office 160 Corporate New York15 New England 50 Eastern Boston20 Mid Atlantic 10 Eastern Washington38 South Atlantic 30 Eastern Atlanta42 Great Lakes 100 Midwest Chicago51 Plains 140 Midwest Dallas66 Pacific 270 Western San Francisco84 Mountain 290 Western Denver
Ⅳ 調用Java存儲過程遇到SQL4306N時怎麼辦
本文講解了在開發Java存儲過程時經常會碰到的一個問題及其解決辦法。
inginStr,intinStart,intinNum)
throwsException
{
if(inStart<1||inStart>inStr.length()||inNum<=0)outStr="";
if((inStart-1+inNum)>inStr.length())inNum=inStr.length()+1-inS
tart;
outStr=inStr.substring(inStart-1,inStart+inNum-1);
}
}
2.創建存儲過程的DDL語句(SpTest.db2):
DROPSPECIFICPROCEDURETESTSUB@
CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE
3.編譯並定義Java存儲過程:
$javacSpTest.java
$cpSpTest.class~/sqllib/function
$db2connecttosample
DatabaseConnectionInformation
Databaseserver=DB2/60008.2.0
SQLauthorizationID=XXXX
Localdatabasealias=SAMPLE
[email protected]
DROPSPECIFICPROCEDURETESTSUB
.DuringSQLprocessingitreturned:
SQL0204N"XXXX.TESTSUB"isanundefinedname.SQLSTATE=42704
CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE
EXTERNALNAME'SpTest.subString'
.
$db2"callsubString(?,'sdafatewfdsa',2,5)"
-definedfunction"XXXX.SUBSTRING",
specificname"TESTSUB"couldnotcallJavamethod"subString",signature
"([Ljava/lang/String;Ljava/lang/Strin".SQLSTATE=42724
我們經過檢查,發現類名正確、類庫也在目錄$HOME/sqllib/function下。這時我們集中精力檢查程序的簽名(Signature)。因為在錯誤信息中,簽名不全,我們要查看$DB2DIAGPATH/db2diag.log文件(其中$DB2DIAGPATH代表資料庫管理器配置參數中的DIAGPATH參數)。我們看到完整的簽名為:
2005-08-17-14.47.19.569936+480I126072C540LEVEL:Warning
PID:1810588TID:1287PROC:db2fmp(Java)0
INSTANCE:XXXXNODE:000
FUNCTION:DB2UDB,BSUJavasupport,sqlejCallJavaRoutine_dll,probe:150
MESSAGE:JNIGetMethodIDfailed.signature:
DATA#1:Hexmp,42bytes
0x3007A950:([Ljava/lang/Str
0x3007A960:;Ljava/lang/S
0x3007A970:7472696E673B49492956tring;II)V
這是DB2用來查找Java存儲過程對應的方法時用的簽名(Signature),此時我們再檢查一下類文件中SubString方法的簽名:
$cd~/sqllib/function
$javap-sSpTest
.Manyprogramlicense
.Ifyouarenottheright
,pleasecheckthe
.
CompiledfromSpTest.java
publicclassSpTestextendsjava.lang.Object{
publicSpTest();
/*()V*/
publicstaticvoidsubString(java.lang.String,java.lang.String,int,int)t
hrowsjava.lang.Exception;
/*(Ljava/lang/String;Ljava/lang/String;II)V*/
我們看到在Java類中的函數簽名與DB2查找的函數簽名不一致。這就是SQL4306N產生的原因。
第一個參數不一樣。根據JNI規范,[Ljava/lang/String是一個String數組。而Ljava/lang/String則是字元串String類型,也就是我們程序源文件中定義的類型。那為什麼DB2要查找一個String數組類型的參數呢?通過查找DB2文檔,我們發現如下解釋(http://publib.boulder.ibm.com/infocenter/db2help/topic/com.ibm.db2.udb.doc/admin/r0008328.htm):
PARAMETERTYPEJAVA
.IN/gvalues..
我們看到如果創建存儲過程時使用了IN/OUT以及OUT參數,DB2會將其解釋為一個單項數組,並通過單項數組傳遞返回值。因此,我們同樣需要在Java程序中使用字元串數組來返回我們的結果。
修改後的java源程序如下所示:
importjava.lang.*;
importjava.io.*;
publicclassSpTest
{
publicstaticvoidsubString(String[]outStr,StringinStr,intinStart,intin
Num)
throwsException
{
if(inStart<1||inStart>inStr.length()||inNum<=0)outStr[0]="";
if((inStart-1+inNum)>inStr.length())inNum=inStr.length()+1-inS
tart;
outStr[0]=inStr.substring(inStart-1,inStart+inNum-1);
}
}
此時我們重新編譯並創建存儲過程,可以看到,它可以正確執行了。
$javacSpTest.java
$cpSpTest.class~/sqllib/function
[email protected]
DROPSPECIFICPROCEDURETESTSUB
.
CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE
EXTERNALNAME'SpTest.subString'
.
$db2"callsubstring(?,'sadfdsafdsaf',2,5)"
Valueofoutputparameters
ParameterName:OUTSTRING
ParameterValue:adfds
ReturnStatus=0
關於SQL4306N的錯誤,基本上通過上面的步驟就可以解決了。如果您的問題通過上面的檢查方法還沒有解決,請聯系IBM技術支持人員。
Ⅳ 安裝了DB2,提示SQL500C系統錯誤,創建不了SAMPLE資料庫,也創建不了owner資料庫(補充如下)
原因在於:
WIN7的 USER ACCOUT CONTROL(UAC)用戶帳戶控制,做完第一步以後,重啟電腦一切OK~~
1.關閉UAC功能的方法是,在「控制面板」→「用戶帳戶」中,點擊「打開或關閉用戶帳戶控制」一項進行設置。而如果想微調UAC功能,則可按選鍵盤上Windows鍵+R鍵,調出「運行」對話框,然後鍵入「secpol.msc」,打開「本地安全策略」設置窗口。
2.在「本地安全設置」窗口中,在窗口左邊依次點擊「本地策略」 →「安全選項」,窗口右邊會對應顯示出多個「用戶帳戶控制」功能的具體設置項目。有經驗的電腦用戶可以根據自己的喜好,對其中的項目作出修改,以符合自己使用電腦的習慣。
3.例如,有些人會將「管理員批准模式中系統管理員的提升行為」由「同意提示」改為「不提示直接提升」;同時將「只提升簽名並驗證的可執行文件」一項由「已禁用」改為「已啟用」。雖然修改設置會削弱UAC本身的效力,但用戶在進行管理操作時卻能減少警告窗口彈出的次數。
4.使用Norton UAC Tool。它可以把UAC設置為始終允許某一程序。安裝後UAC的提示窗口會有一個復選框「始終允許該程序」,這樣可以把某些軟體的升級程序等設為始終放行,方便操作。
5.暫時關閉UAC。先打開任務管理器,結束explorer.exe,然後按下「顯示所有用戶的進程」,會出來一個UAC窗口,放行。然後打開「文件->新任務」,會看到「將以管理員身份運行此程序」,輸入explorer.exe回車,重開桌面,就暫時禁止了UAC。原理:按下「顯示所有用戶的進程」並放行後,任務管理器被提升許可權,在UAC中許可權可以繼承,開啟explorer.exe後,桌面繼承許可權,在桌面上運行的程序也自然繼承了許可權。要開啟UAC,結束explorer.exe再重開,就恢復了。
Ⅵ db2 SQL1390C 環境變數 db2instance未定義
解決方法:
1.在運行中輸入"CMD",進入命令窗口
2.輸入如下命令:db2icrt db2
3.輸入如下命令:set db2instance=db2
Ⅶ SQL3001C 打開輸出文件時,發生 I/O 錯誤(原因碼 = "sqloopen -2029060074")。
看看如下這個文章,也許有幫助
http://www-1.ibm.com/support/docview.wss?rs=71&context=SSEPGG&q1=3508&uid=swg1IY41651&loc=en_US&cs=utf-8&lang=en
在load前看一下設置的TEMPFILE路徑是不是空的,清理之!
如果轉移TEMPFILE路徑後,而且確保目錄許可權沒問題的情況下,如果還有問題,那隻能打一下fixpack試一下啦!
至於你說兩個環境版本完全一致還出這個問題,偶實在沒法解釋!
Ⅷ 如何分析DB2的錯誤信息
DB2資料庫錯誤信息:
com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -407, SQLSTATE: 23502, SQLERRMC: TBSPACEID=2, TABLEID=640, COLNO=0
分析DB2報出的錯誤信息,主要從六個方面進行分析:
SQLCODE, SQLSTATE, SQLERRMC, TBSPACEID, TABLEID, COLNO
1、先從SQLCODE和SQLSTATE兩方面的數字確認是什麼原因(見網址:http://www.knowsky.com/538581.html)
2、在根據TBSPACEID和TABLEID兩方面確認是哪個表
SQL語句:select * from syscat.tables where tbspaceid="" and tableid=""
3、根據COLNO確認是哪個列出問題
SELECT * FROM SYSCAT.COLUMNS WHERE TABNAME= '*******' AND COLNO = 「」
三步就可以精確確認錯誤的原因了
原理分析:在DB2 資料庫中隱藏著一個內部表,專存儲資料庫的各個表。可以通過select * from syscat.tables進行查看。TBSPACEID, TABLEID, COLNO 都是表tables 中的欄位。
=====================================================================
but,
我的DB2資料庫錯誤信息:
com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -532, SQLSTATE: 23504, SQLERRMC: DE_ANOM_DETN.FK_TT_ANOM_TT_DETN_EVNT
根據SQLCODE和SQLERRMC可知:
-532 23504 刪除操作違反了已指定的參照約束
可以判斷出,應該是在刪除級聯表格時,發現參考的外鍵為空了,應該是提前刪除了。
但是我的錯誤信息裡面並沒有上面提示的那麼詳細,上面的是SQLERRMC: TBSPACEID=2, TABLEID=640, COLNO=0 ,而我的是SQLERRMC: DE_ANOM_DETN.FK_TT_ANOM_TT_DETN_EVNT,由此可以推斷出,SQLERRMC裡面的信息就是定位錯誤的核心!!可是這個是什麼呢??估計這個應該找資料庫設計文檔了。
最後沒管這個問題,直接把DB2恢復(restore)一個鏡像點了,然後mq(Qmanager)啟動,was啟動(前提是mq啟動)。問題可能是執行順序或者因為某個伺服器節點未啟動caused的,當這些伺服器節點都正常啟動之後,把資料庫restore正常狀態,然後就可以正常執行了。
Ⅸ 如何在db2命令行運行sql必知必會例子
db2 => connect to dbName user xxx using password
db2 => sql語句
如果要執行一個sql腳本文件:
db2 => quit
c:\> db2 -tvf sql文件名
db2 -td@ -f filename
@是語句結束符。
E:\>db2 ? options
db2 [option ...] [db2-command | sql-statement |
[? [phrase | message | sqlstate | class-code]]]
option:-a、-c、-e{c|s}、-finfile、-lhistfile、-n、-o、-p、-rreport、-s、-t、
-td;、-v、-w、-x 和 -zoutputfile。
選項 描述 預設設置
------ ---------------------------------------- ---------------
-a 顯示 SQLCA OFF
-c 自動落實 ON
-e 顯示 SQLCODE/SQLSTATE OFF
-f 讀取輸入文件 OFF
-l 將命令記錄到歷史文件中 OFF
-n 除去換行字元 OFF
-o 顯示輸出 ON
-p 顯示 db2 互動式提示符 ON
-r 將輸出報告保存到文件 OFF
-s 在命令出錯時停止執行 OFF
-t 設置語句終止字元 OFF
-v 回送當前命令 OFF
-w 顯示 FETCH/SELECT 警告消息 ON
-x 不列印列標題 OFF
-z 將所有輸出保存到輸出文件 OFF
注意:
使用 DB2OPTIONS 環境變數定製選項預設值。
緊跟選項字母後的減號(-)使該選項關閉。
使用 UPDATE COMMAND OPTIONS 更改選項設置(以互動式或
文件輸入方式)。
只能提供nt環境下編寫腳本的例子給你以供參考:
腳本樣例:
db2 connect to yourdb user yourname using yourpassword
db2 insert into newuser(username,password,email) values('Amy','1234','[email protected]')
db2 insert into newuser(username,password,email) values('Judy','1234','[email protected]')
db2 commit
db2 disconnect yourdb
運行腳本: 運行db2cmd X:\XXX.bat
以下摘自本論壇的FAQ可參考:
"
在命令窗口中運行DB2腳本,可用 db2 -svtf 腳本文件名 來實現。
例如,腳本文件名為sample.sql,運行:db2 -svtf sample.sql
參數中:
s 代表遇到錯誤時中止運行腳本
v 代表輸出結果到屏幕
t 指以;號作為每行的分隔符
f 指後面需跟腳本文件名 "---此摘錄版權歸斑竹非本人所有
具體在AS400如何編寫腳本非常遺憾.
db2 -x select SERIALNO from tabname where clause
C:>db2 attach to db2164 user ccp
輸入 ccp 的當前密碼:
實例連接信息
實例伺服器 = DB2/NT 8.2.0
授權標識 = CCP
本地實例別名 = DB2164
C:>db2 connect to dw164 user ccp
輸入 ccp 的當前密碼:
資料庫連接信息
資料庫伺服器 = DB2/NT 8.2.0
SQL 授權標識 = CCP
本地資料庫別名 = DW164
C:>db2 select * from CCP_STS1 fetch first 2 rows only with ur
CUST_ID NOW_PRED_S LOAD_TIME
-------------------- -------------------- --------------------------
3094736. ZFS 2008-05-07-10.02.00.453000
3145886. ZFS 2008-05-07-10.02.00.453000
2 條記錄已選擇。
C:>db2 list command options
命令行處理器選項設置
後端進程等待時間(秒) (DB2BQTIME) = 1
連接至後端的重試次數 (DB2BQTRY) = 60
請求隊列等待時間(秒) (DB2RQTIME) = 5
輸入隊列等待時間(秒) (DB2IQTIME) = 5
命令選項 (DB2OPTIONS) = +m
選項 描述 當前設置
------ ---------------------------------------- ---------------
-a 顯示 SQLCA OFF
-c 自動落實 ON
-d 檢索並顯示 XML 聲明 OFF
-e 顯示 SQLCODE/SQLSTATE OFF
-f 讀取輸入文件 OFF
-i 顯示 XML 數據並帶有縮進 OFF
-l 將命令記錄到歷史記錄文件中 OFF
-m 顯示受影響的行數 OFF
-n 除去換行字元 OFF
-o 顯示輸出 ON
-p 顯示互動式輸入提示符 ON
-q 保留空格和換行符 OFF
-r 將輸出保存到報告文件 OFF
-s 在命令出錯時停止執行 OFF
-t 設置語句終止字元 OFF
-v 回傳當前命令 OFF
-w 顯示 FETCH/SELECT 警告消息 ON
-x 不列印列標題 OFF
-z 將所有輸出保存到輸出文件 OFF
C:>db2set DB2OPTIONS=-x
C:>db2 select * from CCP_STS1 fetch first 2 rows only with ur
4654908. ZFS 2008-05-07-10.02.00.453000
3716687. ZFS 2008-05-07-10.02.00.453000
Ⅹ Db2 中的sql 怎樣實現正則表達式的功能
盡管上面的函數按照預期的方式工作,但還可以改進它以獲得更佳的性能。註:函數內部的執行完成得越快,DB2 處理整個 SQL 語句的速度也就越快。
SQL 旨在處理多組行,這意味著通常會針對一個模式匹配多個行。在大多數情況下,模式本身對於整個 SQL 語句都是不變的;即,它不會隨行的更改而更改。 清單 5 中的 C 代碼展示了對每一行都調用函數 pcre_compile() ,該函數將給定模式轉換成內部表示法。
DB2 通過使用所謂的「高速暫存(scratchpad)」提供了在 UDF 調用之間傳遞信息的機制。此外,您可以標識特定調用「類型」;即它是對該 UDF 的第一次調用、普通調用還是最後一次(最終)調用。使用高速暫存和調用類型,有可能只對模式編譯一次,然後將該已編譯模式的內部表示法重用於對該 UDF 的所有後續調用。在最後一次調用時,釋放在處理期間分配的資源。
如 清單 6所示,對 CREATE FUNCTION 語句進行修改,告訴 DB2 向外部 C 代碼提供高速暫存和調用類型:
清單 6. 將高速暫存和調用類型添加到 CREATE FUNCTION 語句
CREATE FUNCTION regex2(pattern VARCHAR(2048), string CLOB(10M))
RETURNS INTEGER
SPECIFIC regexPerf
EXTERNAL NAME 'regexUdf!regexpPerf'
LANGUAGE C
PARAMETER STYLE DB2SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
SCRATCHPAD 50
FINAL CALL
ALLOW PARALLEL;
UDF 入口點看起來很不一樣,因為必須改寫函數內部的邏輯。參數方面唯一的更改是使用 SQLUDF_TRAIL_ARGS_ALL 代替了 SQLUDF_TRAIL_ARGS ,如 清單 7所示。
清單 7. regex2 的 C UDF 入口點
#include <pcre.h>
#include <sqludf.h>
// data structure mapped on the scratchpad for easier use and access
// to the objects
// the size of the scratchpad defined in the CREATE FUNCTION statement
// must be at least as large as sizeof(scratchPadMapping)
struct scratchPadMapping {
pcre *re;
pcre_extra *extra;
const char *error;
int errOffset;
};
void regexpPerf(
// input parameters
SQLUDF_VARCHAR *pattern, SQLUDF_CLOB *str,
// output
SQLUDF_INTEGER *match,
// null indicators
SQLUDF_NULLIND *pattern_ind, SQLUDF_NULLIND *str_ind,
SQLUDF_NULLIND *match_ind,
SQLUDF_TRAIL_ARGS_ALL) // SQLUDF_SCRAT & SQLUDF_CALLT
{
int rc = 0;
struct scratchPadMapping *scratch = NULL;
// map the buffer of the scratchpad and assume successful return
scratch = (struct scratchPadMapping *)SQLUDF_SCRAT->data;
*match_ind = 0;
switch (SQLUDF_CALLT) {
case SQLUDF_FIRST_CALL:
// initialize data on the scratchpad
scratch->re = NULL;
scratch->extra = NULL;
scratch->error = NULL;
scratch->errOffset = 0;
// compile the pattern (only in the FIRST call
scratch->re = pcre_compile(pattern, 0 /* default options */,
&scratch->error, &scratch->errOffset, NULL);
if (scratch->re == NULL) {
snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
"offset %d: %s\\n", scratch->errOffset, scratch->error);
strcpy(SQLUDF_STATE, "38900");
rc = -1;
break;
}
// further analyze the pattern (might return NULL)
scratch->extra = pcre_study(scratch->re,
0 /* default options */, &scratch->error);
/* fall through to NORMAL call because DB2 expects a result
already in the FIRST call */
case SQLUDF_NORMAL_CALL:
// match the current string
rc = pcre_exec(scratch->re, scratch->extra, str->data,
str->length, 0, 0 /* default options */, NULL, 0);
switch (rc) {
case PCRE_ERROR_NOMATCH:
*match = 0;
rc = 0;
break;
case PCRE_ERROR_BADOPTION:
snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set "
"in the options argument");
strcpy(SQLUDF_STATE, "38901");
rc = -1;
break;
case PCRE_ERROR_NOMEMORY:
snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");
strcpy(SQLUDF_STATE, "38902");
rc = -1;
break;
default:
if (rc < 0) {
snprintf(SQLUDF_MSGTX, 70, "A regexp match error "
"occured: %d", rc);
strcpy(SQLUDF_STATE, "38903");
rc = -1;
}
else {
*match = 1;
rc = 0;
}
break;
}
break;
}
// cleanup in FINAL call, or if we encountered an error in
// the FIRST call (DB2 will make a FINAL call if we encounter
// an error in any NORMAL call)
if (SQLUDF_CALLT == SQLUDF_FINAL_CALL ||
(SQLUDF_CALLT == SQLUDF_FIRST_CALL && rc < 0)) {
(*pcre_free)(scratch->re);
(*pcre_free)(scratch->extra);
}
return;
}
為了進一步改進該函數的性能,我添加了對函數 pcre_study() 的調用,該函數是由模式匹配引擎提供的。該函數進一步分析了該模式,並將額外的信息存儲在獨立的結構中。然後,在實際的匹配期間使用這些額外的信息來加快處理速度。通過使用一個非常簡單的模式和大約 4000 行的表,我獲得了 5% 的執行時間的改善。當然,模式越復雜,差異將越顯著。
我先前提到該實現假定模式在處理期間不會隨行的不同而更改。當然,如果模式確實更改了,您可以進行少量的改寫以再次編譯一個模式。要這樣做,有必要跟蹤當前(已編譯的)模式並在每次調用中將它與所提供的模式進行比較。也可以在高速暫存中維護當前模式。但必須將它復制到獨立的緩沖區,並且不能通過指針模式直接引用它,因為這個指針或它所引用的數據可能會更改或變為無效。至於相應的代碼更改,就當作練習留給讀者了。
返回匹配子串
大多數模式匹配引擎提供了一種方法,返回與指定模式或其一部分相匹配的子串。如果想在 SQL 中使用這種能力,則必須使用不同的方法來實現匹配函數。給定的字元串可能包含不止一個匹配的子串。例如,當解析類似「abc = 123;」或「def = 'some text';」這樣的字元串時,用戶可能會希望檢索由等號分隔的兩個子串。您可以使用模式「\\w+\\s*=\\s*(\\d+|'[\\w\\s] *');」來表示適用於該字元串的語法規則。Perl 兼容的正則表達式允許您捕獲等號兩邊的子串。最後,必須將要捕獲的子串用括弧括起來。我已經用該方式編寫了第二個子串,但第一個子串不是這樣編寫的。用於該用途的最終模式是這樣的:
(\\w+)\\s*=\\s*(\\d+|'[\\w\\s]*');
當把這個模式應用於字元串「abc= 123;」或「def = 'some text';」時,「abc」或「def」分別與「(\\w+)」匹配,空格和等號是通過「\\s*=\\s*」查找的,並用另外的「(\\d+|'[\ \w\\s*]')」涵蓋了餘下的子串。在「(\\d+|'[\\w\\s*]')」中,第一個選項與任何至少由一個數字「\\d+」組成的數匹配,而第二個選項解析任何由字母和空格組成的由單引號括起的字元串「'[\\w\\s]*'」。
在 DB2 中做到這一點的需求可以描述成:為一次 UDF 調用返回多個結果。換句話說,就是返回針對模式進行匹配的單個字元串的多個子串。DB2 的表函數是完成這一任務的完美工具。
實現表 UDF
和以前一樣,必須在資料庫中創建該函數。 清單 8中的下列語句正是用於這一任務的:
清單 8. 注冊名為 regex3 的表 UDF
CREATE FUNCTION regex3(pattern VARCHAR(2048), string CLOB(10M))
RETURNS TABLE ( position INTEGER, substring VARCHAR(2048) )
SPECIFIC regexSubstr
EXTERNAL NAME 'regexUdf!regexpSubstr'
LANGUAGE C
PARAMETER STYLE DB2SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
SCRATCHPAD 50
NO FINAL CALL
DISALLOW PARALLEL;
實現該函數的實際邏輯的 C 代碼與 清單 7中的代碼非常相似,但根據表函數所必須滿足的特殊需求對它進行了改編,如 清單 9所示
你還是看一下這個網站
http://news.weixiuwang.com/server/2006-6/2006E6Y2;1057E89818855_1.htm