Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

       最近遇到一个问题,用户的开发人员编写的一个存储过程中执行LOAD TABLE语句失败,但是在存储过程中不能获得语句执行的状态信息。经过尝试,找到了问题原因和解决方法,在这里与大家分享。由于涉及用户保密的原因,本文对用到的测试表、存储过程等进行了修改,但是同样能够说明问题!

一、问题再现

-- 1. 创建测试表 (crt_table.sql)

create table test11 (

id int not null  ,

age tinyint null  ,

name char (8)  null ,

primary key (id)

)

  --2. 准备数据文件/tmp/test11.dat

1|!aaaaaaaa|!

2|!bbbbbbbb|!

3|!cccccccc|!

  --3. 创建存储过程 (crt_proc.sql)

CREATE PROCEDURE proc1()

BEGIN

declare @sqlcode int;

message 'load table test11' type info to client ;

LOAD TABLE test11

(

  id    '|!'    ,

  name  '|!'

)

FROM '/tmp/test11.dat'

FORMAT ASCII

STRIP ON

ESCAPES OFF

QUOTES OFF

NOTIFY 500000

ROW DELIMITED BY '\x0a'

WITH CHECKPOINT ON;

SELECT sqlcode INTO @sqlcode;

IF @sqlcode <> 0 THEN

  message  'load table sqlcode = ', @sqlcode, '; error msg = ', errormsg(@sqlcode) type info to client;

END IF;

END;    --proc1 end

   --4. 使用dbisql执行crt_table.sql和crt_proc.sql脚本,创建测试表和测试存储过程。并把test11.dat文件放入/tmp目录。

   --5. 使用dbisql或isql 连接到IQ Server,执行存储过程proc1.

   (1) 在第一次执行的时候成功,下面是我环境下的输出:

sybiq152@HAIQ-DB-01:~/case_work/proc_load_sqlcode> dbisql -c "uid=DBA;pwd=sql" -nogui -onerror continue

(DBA)> proc1

load table test11

1 row(s) affected

Execution time: 0.081 seconds

   (2) 在执行第二次的时候报错(因为有重复记录了),proc1存储过程中load语句之后的 IF 语句没有执行。

sybiq152@HAIQ-DB-01:~/case_work/proc_load_sqlcode> dbisql -c "uid=DBA;pwd=sql" -nogui -onerror continue

(DBA)> proc1

load table test11

Could not execute statement.

Tried to insert a duplicate value into a unique index

DBA.test11.ASIQ_IDX_T754_I4_HG on row 4.

-- (s_ohcins.cxx 722)

SQLCODE=-1002003, ODBC 3 State="HY000"

Line 1, column 1

proc1

(Continuing after error)

 

二、解决方法

解决方法 1: 在存储过程外部判断sqlcode

    在这种情况下,当存储过程中的某个SQL语句执行出错时,IQ会终止存储过程的执行,不会再执行出错语句后面的存储过程代码。解决它的办法之一是在调用存储过程之后,在存储过程外部判断sqlcode。例如, 在调用proc1之后,立即执行

select sqlcode,@@error, errormsg(sqlcode) ,这样是可以获得错误代码和错误消息的:

 

(DBA)> select sqlcode,@@error, errormsg(sqlcode)

 

sqlcode     @@error     errormsg(sqlcode)                                                                                                                                                                                                                                               

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-1002003    -6          Tried to insert a duplicate value into a unique index ??? on row ???. ???

解决方法 2: 修改存储过程定义,增加 on exception resume 字句。

下面是修改后的存储过程代码:

CREATE PROCEDURE proc1 ()

ON EXCEPTION RESUME

BEGIN

declare @sqlcode int;

message 'load table test11' type info to client ;

LOAD TABLE test11

(

  id    '|!'    ,

  name  '|!'

)

FROM '/tmp/test11.dat'

FORMAT ASCII

STRIP ON

ESCAPES OFF

QUOTES OFF

NOTIFY 500000

ROW DELIMITED BY '\x0a'

WITH CHECKPOINT ON;

SELECT sqlcode INTO @sqlcode;

IF @sqlcode <> 0 THEN

  message  'load table sqlcode = ', @sqlcode, '; error msg = ', errormsg(@sqlcode) type info to client;

END IF;

END;

   执行修改后的存储过程,输出如下:

sybiq152@HAIQ-DB-01:~/case_work/proc_load_sqlcode> dbisql -c "uid=DBA;pwd=sql" -nogui -onerror continue

(DBA)> proc1
load table test11
load table sqlcode = -1002003; error msg = Tried to inserta duplicate value into a unique index ??? on row ???. ???
1 row(s) affected
Execution time: 0.016 seconds


   这次执行,存储过程proc1内部的IF语句被执行了!

Top kudoed authors