Two DB2 SQLCODEs show up in every COBOL FETCH loop and almost every singleton SELECT: 0 (successful execution) and +100 (no row found). Mixing them up—or treating +100 like a crash—is the most common embedded-SQL bug on z/OS. This page is the IBM meaning of each, the SQLSTATE, what happens to host variables, and how to code the loop.
IBM’s successful-execution topic is numbered 000. The integer in the SQLCA is 0. Programmers write +000 in tables so it sits next to +100. There is no different “plus zero” value.
System action: the statement completed. INSERT/UPDATE/DELETE changed the rows that qualified (count in SQLERRD(3) / GET DIAGNOSTICS ROW_COUNT). FETCH filled host variables. OPEN positioned the cursor before the first row (the first FETCH still has to run).
Programmer response: if SQLWARN0 is W, do not ignore it in programs that care about truncation (SQLWARN1), nulls dropped from AVG (SQLWARN2), or extra result columns (SQLWARN3). GET DIAGNOSTICS MESSAGE_TEXT is empty when SQLCODE is 0 even if SQLSTATE indicates a warning—use the SQLWARN flags or CONDITION items, not MESSAGE_TEXT, for that case.
1234567891011EXEC SQL UPDATE EMP SET SALARY = SALARY * 1.03 WHERE DEPTNO = :HV-DEPT END-EXEC. IF SQLCODE = 0 DISPLAY 'ROWS UPDATED ' SQLERRD(3) IF SQLWARN0 = 'W' PERFORM REVIEW-WARNINGS END-IF END-IF.
IBM text: ROW NOT FOUND FOR FETCH, UPDATE OR DELETE, OR THE RESULT OF A QUERY IS AN EMPTY TABLE. SQLSTATE 02000. System action: no data was retrieved, updated, or deleted—with the rowset exception below.
| Situation | What it means |
|---|---|
| FETCH after last row | Normal cursor loop end. Do not process hosts as a new row. |
| SELECT INTO empty | Singleton found nobody. Distinct from -811 (too many rows). |
| UPDATE/DELETE no match | Zero rows qualified. SQLERRD(3) is 0. Not a constraint error. |
| INSERT … SELECT empty | Nothing inserted because the subselect produced no rows. |
| Partial rowset FETCH | Not enough rows for a full rowset; SQLERRD(3) has how many came back. |
| SKIP LOCKED DATA | No available row under CS/RS with SKIP LOCKED DATA. |
The pattern is OPEN, FETCH, process while SQLCODE is 0, FETCH until +100, CLOSE. Testing +100 after PROCESS is too late if you process first. Never treat +100 as “use the hosts anyway.”
12345678910EXEC SQL OPEN C1 END-EXEC. EXEC SQL FETCH C1 INTO :HV-EMPNO, :HV-LNAME END-EXEC. PERFORM UNTIL SQLCODE = +100 IF SQLCODE NOT = 0 PERFORM SQL-ERROR END-IF PERFORM WRITE-REPORT-LINE EXEC SQL FETCH C1 INTO :HV-EMPNO, :HV-LNAME END-EXEC END-PERFORM. EXEC SQL CLOSE C1 END-EXEC.
SELECT INTO with one row expected: 0 means you have the row, +100 means it does not exist, -811 means more than one row (use a cursor or tighten the predicate). Those three codes are the whole singleton story.
A searched UPDATE that matches nothing is +100, not an error. SQLERRD(3) is 0. That is different from -803 (duplicate) or -530 (RI). Your business rule decides whether zero rows is acceptable.
If you asked for a rowset of 20 and only 7 remain, IBM documents +100 with a partial rowset: data is returned only for the rows actually fetched, and SQLERRD(3) (or ROW_COUNT) is 7. Process those 7, then end the loop. Do not discard the partial set.
In SPUFI, +100 on a SELECT is normal completion. IBM also documents +100 when LOB data cannot be returned (for example isolation UR while the LOB table space is locked). That is easy to misread as “empty table” when the base row exists—check isolation and LOB locks if a LOB SELECT INTO surprises you with +100.
Both 0 and +100 are non-negative. WHENEVER SQLERROR does not catch +100; WHENEVER NOT FOUND does. SQL PL CONTINUE HANDLER FOR NOT FOUND is the +100 handler. Do not DECLARE HANDLER FOR SQLEXCEPTION expecting to see empty FETCH—that is NOT FOUND, class 02, not an exception.
GET DIAGNOSTICS after +100: ROW_COUNT is 0 for a failed singleton or empty searched UPDATE; for a partial rowset it is the short count. DB2_RETURNED_SQLCODE is +100. MESSAGE_TEXT describes the not-found condition.
You ask for a cookie. SQLCODE 0 is “here is your cookie” (sometimes the cookie is slightly crumbled—that is a warning flag, still a cookie). SQLCODE +100 is “the jar is empty.” Empty is not the same as “I dropped the jar and we have to sweep the kitchen” (a negative code). A FETCH loop is reaching into the jar until the empty answer, counting only the cookies you actually got.
1. SQLCODE 0 with SQLWARN0 = W means:
2. SQLCODE +100 is returned when:
3. After FETCH returns +100, host variables:
4. Is +100 an error for SPUFI SELECT?
5. WHENEVER NOT FOUND GOTO END-LOOP is tied to: