当前位置:首页 » 编程语言 » db2sql3007c
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

db2sql3007c

发布时间: 2022-05-12 03:45:15

Ⅰ 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