免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7155 | 回复: 14
打印 上一主题 下一主题

SQLRPGLE的诸多问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-10-28 14:01 |只看该作者 |正序浏览
我写了一个SQLRPGLE的小程序,功能是提取一个PF中所有数据,赋给变量,然后用变量更新或者插入数据给另一个PF。但是现在遇到2个问题:
1.运行程序后,如果想要CLRPFM第2个PF,提示:MEMBER正在使用中。必须
  注销重新登陆才行,这是为什么??
2.代码可能有问题,我执行程序后,他只读取了第一个PF中第1和第3条记录,而且只能插入不能更新,我 晕~ 请大人帮我看看代码。
---声明变量
0001.00 DVXHEMPID         S              3A                                   
0002.00 DVXHNAME          S             15A                                   
0003.00 DVXHJOB           S             10A                                   
0004.00 DISEXIST          S              5S 0                                 

----声明游标
0005.00 C/EXEC SQL                                                            
0006.00 C+ DECLARE C1 CURSOR FOR SELECT XHEMPID,XHNAME,XHJOB FROM XHZQ        
0007.00 C/END-EXEC                                                            

---打开游标
0008.00 C/EXEC SQL                                                            
0009.00 C+ OPEN C1                                                            
0010.00 C/END-EXEC                                                            

---当没有出错的时候把游标里的值赋给变量
0011.00 C                   DOW       SQLCOD = 0                              
0012.00 C/EXEC SQL                                                            
0013.00 C+ FETCH C1 INTO :VXHEMPID,:VXHNAME,:VXHJOB                           
0014.00 C/END-EXEC                                                            

---用变量VXHEMPID作为关键字来查找记录是否存在
0015.00 C/EXEC SQL                                                            
0016.00 C+ SELECT COUNT(*) INTO :ISEXIST FROM XHZQ1 WHERE XHEMPID1 = :VXHEMPID

---如果不存在就插入记录
0017.00 C/END-EXEC                                                            
0018.00 C                   IF        ISEXIST = 0                             
0019.00 C/EXEC SQL                                                            
0020.00 C+ INSERT INTO XHZQ1(XHEMPID1,XHNAME1,XHJOB1)  
0021.00 C+ VALUES(:VXHEMPID,:VXHNAME,:VXHJOB)         
0022.00 C/END-EXEC                                    
0023.00 C                   ENDIF                     

---如果存在就更新记录
0024.00 C                   IF        ISEXIST = 1      
0025.00 C/EXEC SQL                                    
0026.00 C+ UPDATE XHZQ1                                
0027.00 C+ SET XHNAME1 = :VXHNAME,                     
0028.00 C+     XHJOB1 = :VXHJOB                        
0029.00 C/END-EXEC                                    
0030.00 C                   ENDIF                     

---继续读下一个记录
0031.00 C/EXEC SQL                                    
0032.00 C+ FETCH C1 INTO :VXHEMPID,:VXHNAME,:VXHJOB   
0033.00 C/END-EXEC                                    
0034.00 C                   ENDDO                     

---关闭游标
0035.00 C/EXEC SQL                                    
0036.00 C+ CLOSE C1                                    
0037.00 C/END-EXEC                                    

---提交所做的更改
0038.00 C/EXEC SQL                                    
0039.00 C+ COMMIT                                      
0040.00 C/END-EXEC               
---结束
0041.00 C                   RETURN

论坛徽章:
0
15 [报告]
发表于 2013-05-22 22:48 |只看该作者
xuguopeng 发表于 2003-10-31 19:47
谢谢指教~~ 你说的:IND指示变量,我还有点不太明白,可以举个例子么?
SQLCOD = 100 就是SQLSTATE = ‘02 ...


指示器变量主要有两个用途:1,标记空值;2,标记截断。
具体来说:
1,select sum(x) into :var :ind from mytab where ....
如果where条件限制下并无满足条件的的记录,那么sum(x)应该为空值。可是,这个“NULL”如何告知程序的宿主变量呢?标准规定:如果是空值,那么ind置为小于零(-1)的值;
同样的,如果要插入空值,ind=-1; insert into mytab (x) values (:var :ind); 即可。
2,标记截断
var长度为1,那么select 'ab' into :var :ind from mytab .....
显然,‘ab'并不能完整的放入变量var,标准规定,此时ind置为大于0的值(1)。

3,特别的,在您的例子里面,
select count(*) into :var ....
这个聚合是肯定不需要使用:ind的,因为这条语句肯定有唯一的一条记录,不可能出现NULL。

4,最后,一般而言,并不需要select count(*)预先进行存在性判定;直接update即可,如果SQLCODE>0表明并不存在该记录,在直接插入该记录即可。

论坛徽章:
0
14 [报告]
发表于 2003-11-01 17:21 |只看该作者

SQLRPGLE的诸多问题

明白了 SQLERROR是全局变量么?可以直接引用??

论坛徽章:
0
13 [报告]
发表于 2003-11-01 17:16 |只看该作者

SQLRPGLE的诸多问题

我理解指示器变量的目的与MONMSG作用类似,出错的话若没有此定义,则会进入异常处理,而定义了则表示你会在程序中做出错的处理,所以有此定义则程序会继续执行下去,否则执行*PSSR或作业MSGW。所以,在COUNT之后最好定义,以免意外中断.

SQLWNO是WARNING NO,没用过.我一般用
C+ WHENEVER SQLERROR GOTO XXXTAG

来监控SQL错误,XXXTAG是SQL错误处理的语句标号,其后是错误的善后处理.

论坛徽章:
0
12 [报告]
发表于 2003-10-31 19:47 |只看该作者

SQLRPGLE的诸多问题

谢谢指教~~ 你说的:IND指示变量,我还有点不太明白,可以举个例子么?
SQLCOD = 100 就是SQLSTATE = ‘02000’吧,也就是检索到底没有找到数据的意思?
还有SQLWN0<>;*BLANKS 这个是什么意思??SQLWN0是什么?也是全局变量么??

论坛徽章:
0
11 [报告]
发表于 2003-10-31 17:37 |只看该作者

SQLRPGLE的诸多问题

SELECT COUNT(*) INTO :ISEXIST [b]:IND[/b]

:IND 就是指示器变量,作用就象WRITE 语句的出错指示器一样。

SQLCOD =100是最常用的,在SELECT UPDATE DELETE 之后,或FETCH已经检索到最后一个可用行。

在SELECT UPDATE DELETE INSERT 语句后最好加上错误处理:

SELECT
WHEN  SQLCOD <0
EXSR    SQLERROR
WHEN  SQLCOD =100
EXSR    SQLNOROW
WHEN  SQLCOD >;0 OR SQLWN0<>;*BLANKS
EXSR    SQLWARNING
ENDSL

论坛徽章:
0
10 [报告]
发表于 2003-10-31 14:10 |只看该作者

SQLRPGLE的诸多问题

我明白的,只是想测试一下游标的使用方法。SQLCOD我已经引用了呀,但是我只知道SQLSTATE =‘00000’是正常,=‘00010’是警告,=‘00020’是错误,SQLCOD=0是正常,其他的就没细研究。
ISEXIST后面加指示器?? 我后面也有写如果ISEXIST=0做什么啊?吸取宝贵经验了~~~

论坛徽章:
0
9 [报告]
发表于 2003-10-31 13:36 |只看该作者

SQLRPGLE的诸多问题

我的经验是少用游标,麻烦!

你这种情况,2个SQL语句就可以了,也许你只是想研究一下游标用法?

1、UPDATE FILE1 SET FLDX = VALUEX  WHERE FLDY = VALUEY

2、INSERT INTO FILE2 VALUES (XXX) WHERE NOT EXISTS (SELECT * FROM FILE1 WHERE FLDY = VALUEY)

另外,SELECT COUNT(*)INTO 后面的变量:ISEXIST 后面一定要加一个指示器变量,否则若记录未找到时会出错,我遇到过的。

SQLCODE 变量判断记录是否存在及执行结果是否出错比较好用,你可以试着用一下。
推荐你一本书,很好,《DB2 400 数据库设计与编程》

论坛徽章:
0
8 [报告]
发表于 2003-10-28 19:54 |只看该作者

SQLRPGLE的诸多问题

解决了~ UPDATE放在INSERT前面就可以了,怪了,如果先INSERT就不行

论坛徽章:
0
7 [报告]
发表于 2003-10-28 19:20 |只看该作者

SQLRPGLE的诸多问题

果然不出子樵所料。。。。。。。
加上WHERE CURRENT OF C1了也是更新不了,只能插入,而且只能插入1,3,4,5。。。。。。的记录,第2条记录总插不上,郁闷~~
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP