英文:
Is there a way to obtain the SQLSTT error description in RPGLE/DB2 SQL for more informative error messages?
问题
I am running RPGLE/DB2 SQL and want to get the SQLSTT error description to send back to the user or developers to better describe what happened. Right now we have to google the SQLSTT description after receiving the error.
This seems like something I should be able to query from somewhere but I cannot find the solution.
PSTMT='create or replace alias QTEMP.TheirIIM for '
+%trim(xOtherSys)+'IIM';
exec sql execute immediate :PSTMT;
@SQLERR(SQLSTT:'ALIAS' :%trim(xOtherSys)+'IIM');
Dcl-proc @SQLERR;
Dcl-pi @SQLERR IND;
SQLSTATE CHAR(5) const;
Action CHAR(20) const;
File CHAR(20) const;
End-pi;
Select;
When ACTION = 'ALIAS'; // Create Alias failed
** If SQLSTT > '03000';**
Subject = %Trim(DFTLIB) + ' ' +
'INTCRTORD Pgm Error: Create Alias failed. ';
Message = %Trim(ACTION) +
': CREATE ALIAS for '+ %Trim(File) +
' statement failed with SQLSTT:'+SQLSTT+
'\n RUN ABORTED!';
$Error = *ON;
ENDIF;
I'd like to actually retrieve what the SQLSTT means and send that back in my message.
英文:
I am running RPGLE/DB2 SQL and want to get the SQLSTT error description to send back to the user or developers to better describe what happened. Right now we have to google the SQLSTT description after receiving the error.
This seems like something I should be able to query from somewhere but I cannot find the solution.
PSTMT='create or replace alias QTEMP.TheirIIM for '
+%trim(xOtherSys)+'IIM';
exec sql execute immediate :PSTMT;
@SQLERR(SQLSTT:'ALIAS' :%trim(xOtherSys)+'IIM');
Dcl-proc @SQLERR;
Dcl-pi @SQLERR IND;
SQLSTATE CHAR(5) const;
Action CHAR(20) const;
File CHAR(20) const;
End-pi;
Select;
When ACTION = 'ALIAS'; // Create Alias failed
** If SQLSTT > '03000';**
Subject = %Trim(DFTLIB) + ' ' +
'INTCRTORD Pgm Error: Create Alias failed. ';
Message = %Trim(ACTION) +
': CREATE ALIAS for '+ %Trim(File) +
' statement failed with SQLSTT:'+SQLSTT+
'\n RUN ABORTED!';
$Error = *ON;
ENDIF;
I'd like to actually retrieve what the SQLSTT means and send that back in my message.
答案1
得分: 3
You can also get the full error message with the SQL function:
get diagnostics
The MESSAGE-TEXT contains the detailed error message:
DCL-S DataText VARCHAR(200);
Exec SQL
prepare c1 from :sqlw ;
if (SQLCOD < 0);
Exec SQL GET DIAGNOSTICS EXCEPTION 1
: DataText = MESSAGE_TEXT ;
snd-msg DataText;
ENDIF;
See the IBM documentation GET DIAGNOSTICS or detailed examples in Simon's blog.
英文:
You can also get the full error message with the sql function :
get diagnostics
The MESSAGE-TEXT contain the detailed error message :
DCL-S DataText VARCHAR(200);
Exec SQL
prepare c1 from :sqlw ;
if (SQLCOD < 0);
Exec SQL GET DIAGNOSTICS EXCEPTION 1
: DataText = MESSAGE_TEXT ;
snd-msg DataText;
ENDIF;
see the IBM documentation
GET DIAGNOSTICS
答案2
得分: 2
"The SQLCODE ties directly to an IBM i error message description."
这段文字直接与IBM i错误消息描述相关。
"Return *ON for success; *OFF for failure"
成功时返回ON;失败时返回OFF。
"Send a message to the program message queue if a failure occurs."
如果发生失败,向程序消息队列发送一条消息。
"Unspecified location"
未指定位置
"If SQLCOD = -842 and SQLSTT = '08002' ; // Already connected"
如果SQLCOD = -842且SQLSTT = '08002'; // 已连接
"Couldn't think of another way to word it with readability"
无法想出另一种更具可读性的表达方式
"Error occurred at"
发生错误于
"Abort due to SQL error at"
由于SQL错误中止
"CPI8859"
CPI8859
"CPF9898"
CPF9898
"Abort due to SQL error at"
由于SQL错误中止
英文:
Edit: You need to use the SQLCODE instead of the SQLSTATE.
The SQLCODE ties directly to an IBM i error message description.
You may like this snippit from one of my RPGLE SQL programs:
*********************************************************************
* Determine the Success/Failure of an SQL operation by checking *
* SQLCODE and SQLSTATE. *
* --- *
* Return *ON for success; *OFF for failure *
* --- *
* Send a message to the program message queue if a failure occurs. *
*********************************************************************
P CheckSQL B
D CheckSQL PI N
D EOF_IS_OK N Const Options(*NoPass)
D ParmWarnOnly N Const Options(*NoPass)
D ParmLocation 32 Const Varying
D Options(*NoPass)
D WarningOnly S N Inz(SQL_ABORT)
D StmtLocation S 32 Varying
D Inz('Unspecified location')
D SQLerrID S 7
D SuccessFlag S N
D IgnoreEOF S N Inz(*On)
/Free
If %Parms > 0 ;
IgnoreEOF = EOF_IS_OK ;
If %Parms > 1 ;
WarningOnly = ParmWarnOnly ;
If %Parms > 2 ;
StmtLocation = ParmLocation ;
EndIF ;
EndIF ;
EndIF ;
SQLErrID = *Blanks ;
SuccessFlag = *On ;
Select ;
When SQLCOD = -842 and SQLSTT = '08002' ; // Already connected
SuccessFlag = *On ;
SQLerrID = 'SQL9999' ;
When SQLCOD = 100 and IgnoreEOF ;
SuccessFlag = *On ;
When SQLSTT <> *Zero ;
SuccessFlag = *Off ;
SQLerrID = 'SQL9999' ;
When SQLCOD <> *Zero ;
SuccessFlag = *Off ;
SQLerrID = 'SQL9999' ;
When SQLCOD = *Zero ;
SuccessFlag = *On ;
Other ;
SuccessFlag = *On ;
EndSL ;
If SQLCOD = *Zero or (SQLCOD = 100 and IgnoreEOF) ;
// Couldn't think of another way to word it with readability
Else ;
EvalR SQLerrID = %EditC(%Abs(SQLCOD): 'X') ;
If %Subst(SQLerrID: 3: 1) = '0' ;
%Subst(SQLerrID: 1: 3) = 'SQL' ;
Else ;
%Subst(SQLerrID: 1: 2) = 'SQ' ;
EndIF ;
AcePgmMsg(SQLerrID: SQLERM: '*COMP') ;
EndIF ;
If Not SuccessFlag ;
If WarningOnly ;
AcePgmMsg('CPI8859'
: 'Error occurred at ' + StmtLocation: '*COMP') ;
Else ;
SendEscape('CPF9898'
: 'Abort due to SQL error at ' + StmtLocation
) ;
EndIF ;
EndIF ;
Return SuccessFlag ;
/End-free
P CheckSQL E
This works by utilizing the SQL error messages file QSQLMSGF. SQLERM is the error code you're looking for. I think you an figure out AcePgmMsg and create your own.... all it does, is SNDPGMMSG with the appropriate MSGID and MSGF specified, with MSGTYPE set to the specified value. So if it's not clear, let's say you have an SQLERM value of 1234. Look at the message description for SQL1234 of message file QSQLMSGF and you will find what that error code means. FOr values above 9999, the message code is SQ + code (SQ23456). So, at a minimum, you can stop doing google searches; the answer is local to your system.
Let me know if you need more.
Have fun.
答案3
得分: 0
要控制错误,通常我们使用 SQLCODE(这已经在这里写过了) - 值为0表示成功执行,负值表示错误。
可以通过 get diagnostics condition 来获取具体的错误类型和详细描述。例如像这样:
begsr isSQLError;
If SQLCOD < 0;
exec sql get diagnostics condition 1 :ErrState = RETURNED_SQLSTATE, :errText = MESSAGE_TEXT;
LogText(MpJobName + errText);
LogMsg(errCode: ErrState);
return *off;
EndIf;
endsr;
或者,如果您愿意,您可以将其安排为单独的过程。
英文:
To control the error, we usually use SQLCODE (this has already been written about here) - the value 0 corresponds to successful execution, negative values - an error.
The specific error type and its detailed description can be obtained via get diagnostics condition. For example like this:
begsr isSQLError;
If SQLCOD < 0;
exec sql get diagnostics condition 1 :ErrState = RETURNED_SQLSTATE, :errText = MESSAGE_TEXT;
LogText(MpJobName + errText);
LogMsg(errCode: ErrState);
return *off;
EndIf;
endsr;
Well, or, if you like, you can arrange it as a separate procedure.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论