• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Down with Assumptions! Up with Diagnostics!

    November 10, 2010 Ted Holt

    Even though assumptions have no place in proper programming, programmers sometimes infuse their code with assumptions. Such practice brings to mind something I once read: If builders built houses the way programmers write programs, the first woodpecker to come along would destroy civilization. I’ve written about the problem of assumptions before. Today is a good day to revisit the subject.

    Programmers who cut their teeth on native I/O (as did I) often depend on the system to alert them when something goes wrong. That is, they assume an I/O operation completed normally unless they hear differently. The bad way to hear differently is to read a message on message queue QSYSOPR. The proper way to hear differently is to trap the error (e.g., with RPG’s MONITOR op code) and do something with it. But trade schools and OJT aren’t the best teachers of error recovery.

    One of the most notable ways that SQL differs in many ways from native I/O is that SQL does not generate a hard error when it can’t complete an assignment. Instead, SQL updates a multitude of variables and program execution continues. Two of those variables are SQL state and SQL code. (I have also written about them.)

    Each time the system executes an SQL command, it updates a diagnostics area with a plethora of information. Use the GET DIAGNOSTICS statement to retrieve this information.

    You may retrieve three types of information:

    • Statement
    • Connection
    • Condition

    One option is to retrieve all of the information, as this short program does.

    D Data            s           1049a   varying
     /free
         *inlr = *on;
         exec sql
            update custcdt
               set baldue = 999
             where state = 'TX';
         exec sql
            get diagnostics
                 :Data = All;
         return;
    

    This impractical program decrees that all Texas customers are in debt to the tune of 999 simoleons. After the update, GET DIAGNOSTICS loads the DATA variable with a lot of information. It’s one long string, but here I show the V5R4 version wrapped 60 characters to the line (as the green-screen debugger shows it).

    COMMAND_FUNCTION=UPDATE WHERE;COMMAND_FUNCTION_CODE=+82;DB2_
    NUMBER_CONNECTIONS=+1;DB2_SQL_ATTR_CONCURRENCY=L;DB2_SQL_ATT
    R_CURSOR_HOLD=N;DB2_SQL_ATTR_CURSOR_ROWSET=N;DB2_SQL_ATTR_CU
    RSOR_SCROLLABLE=N;DB2_SQL_ATTR_CURSOR_SENSITIVITY=S;DB2_SQL_
    ATTR_CURSOR_TYPE=F;MORE=N;NUMBER=+1;ROW_COUNT=+2;CLASS_ORIGI
    N=ISO 9075;CONDITION_NUMBER=+1;DB2_MESSAGE_ID=SQL7957;DB2_MO
    DULE_DETECTING_ERROR=QSQUPDAT;DB2_ORDINAL_TOKEN_1=CUSTCDT   
    ;DB2_ORDINAL_TOKEN_2=QTEMP     ;DB2_ORDINAL_TOKEN_3=2;DB2_OR
    DINAL_TOKEN_4=0;DB2_TOKEN_COUNT=+4;DB2_TOKEN_STRING=CUSTCDT 
      QTEMP     20;MESSAGE_LENGTH=+35;MESSAGE_OCTET_LENGTH=+3
    5;MESSAGE_TEXT=2 rows updated in CUSTCDT in QTEMP.;RETURNED_
    SQLSTATE=00000;SERVER_NAME=Z1010101;SUBCLASS_ORIGIN=ISO 9075
    ;CONNECTION_NAME=Z1010101;DB2_AUTHORIZATION_ID=SMITH;DB2_CON
    NECTION_METHOD=D;DB2_CONNECTION_NUMBER=+1;DB2_CONNECTION_STA
    TE=+1;DB2_CONNECTION_TYPE=+1;DB2_PRODUCT_ID=QSQ05040;DB2_SER
    VER_CLASS_NAME=DB2 UDB for iSeries;DB2_SERVER_NAME=Z1010101;
    

    Notice the format of the string–keyword=value–separated by semicolons.

    If you don’t want all the information, there are various ways to get only part of it. Here’s the same worthless program, but this version retrieves the statement information only.

    D Data            s           1049a   varying
     /free
         *inlr = *on;
         exec sql
            update custcdt
               set baldue = 999
             where state = 'TX';
         exec sql
            get diagnostics
                 :Data = All Statement;
         return;
    

    Notice there are fewer keyword/value pairs.

    COMMAND_FUNCTION=UPDATE WHERE;COMMAND_FUNCTION_CODE=+82;DB2_
    NUMBER_CONNECTIONS=+1;DB2_SQL_ATTR_CONCURRENCY=L;DB2_SQL_ATT
    R_CURSOR_HOLD=N;DB2_SQL_ATTR_CURSOR_ROWSET=N;DB2_SQL_ATTR_CU
    RSOR_SCROLLABLE=N;DB2_SQL_ATTR_CURSOR_SENSITIVITY=S;DB2_SQL_
    ATTR_CURSOR_TYPE=F;MORE=N;NUMBER=+1;ROW_COUNT=+2;
    

    A big disadvantage of retrieving values by the bunch is that you have to write code to extract the values from a long string. But if you retrieve values individually, you don’t have to go through that ordeal. In the following example, GET DIAGNOSTICS determines how many rows were updated.

    D RowCount        s             10i 0
     /free
         *inlr = *on;
         exec sql
            update custcdt
               set baldue = 999
             where state = 'TX';
         exec sql
            get diagnostics
                 :RowCount = ROW_COUNT;
         return;
    

    The system loads ROWCOUNT with the number of records that were updated. By the way, this is a more intuitive method than the one I published previously.

    If you need to obtain two or more values at once, you can do that too, like this:

    D RowCount        s             10i 0
    D Command         s            128a   varying
     /free
         *inlr = *on;
         exec sql
            update custcdt
               set baldue = 999
             where state = 'TX';
         exec sql
            get diagnostics
                 :RowCount = ROW_COUNT,
                 :Command  = COMMAND_FUNCTION;
         return;
    

    After this code runs, ROWCOUNT contains an integer value and COMMAND is UPDATE WHERE.

    The last two examples retrieved two of the STATEMENT information values. This one retrieves TABLE_NAME from the CONDITION information.

    D TotalDue        s              9p 2
    D TableName       s            128a   varying
     /free
         *inlr = *on;
         exec sql
            select sum(baldue)
              into :TotalDue
              from br549;
         exec sql
            get diagnostics
                 condition 1 :TableName = TABLE_NAME;
         return;
    

    After GET DIAGNOSTICS, TABLENAME is BR549.

    See the SQL Reference for your release to learn more about the values in the diagnostics area.

    The lesson is clear: There is no need to assume anything when an SQL statement runs. SQL gives you more information than what you want or need.

    RELATED STORIES

    How Many Rows Did SQL Fetch?

    Error Checking and Embedded SQL

    Programming with Assertions



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    ARCAD Software

    [Webinar] Synchronous IBM i and non-IBM i Deployments
    April 13 at 12 p.m. ET

    Do you need to automate and synchronize deployments across ALL your environments and applications?

    Many backend IBM i applications have off-platform components, such as an API layer, or Web front-end. To ensure your application stays reliable, artifacts must be deployed securely and in-sync.

    In our Webinar, learn how to orchestrate all your deployments, multi-platform and multi-cloud, using DROPS by ARCAD Software:

    – One single console to deploy across multiple endpoints – IBM i, Windows, Linux, IBM z, on prem or cloud

    – Real-time visibility of application status, from anywhere

    – Deployment plans and one-click-deploy

    – Rollback on error

    Simplify and secure your application delivery.

    Register Now

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    Bytware:  FREE Webinar! Scan your IBM i, AIX, and Linux Directories for Viruses. Nov. 17, 9 am PT
    iSeries DevCon2010:  Get 3 days of IBM i training and 365 DAYS OF VALUE, Nov 15-17, Las Vegas
    Profound Logic Software:  FREE Webinar: Creating Open and Portable IBM i Apps. Nov 16, 1 p.m. EST

    IT Jungle Store Top Book Picks

    BACK IN STOCK: Easy Steps to Internet Programming for System i: List Price, $49.95

    The iSeries Express Web Implementer's Guide: List Price, $49.95
    The iSeries Pocket Database Guide: List Price, $59
    The iSeries Pocket SQL Guide: List Price, $59
    The iSeries Pocket WebFacing Primer: List Price, $39
    Migrating to WebSphere Express for iSeries: List Price, $49
    Getting Started with WebSphere Express for iSeries: List Price, $49
    The All-Everything Operating System: List Price, $35
    The Best Joomla! Tutorial Ever!: List Price, $19.95

    Attachmate Partners with Emirates for Airline App JDE Alliance Formed by Six Independent Vendors

    Leave a Reply Cancel reply

Volume 10, Number 35 -- November 10, 2010
THIS ISSUE SPONSORED BY:

WorksRight Software
ProData Computer Services
Twin Data Corporation

Table of Contents

  • Two Tips Are Better Than One
  • Down with Assumptions! Up with Diagnostics!
  • Admin Alert: Things to Think About When Changing Hardware Maintenance

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • LANSA Developing Business Intelligence Tool
  • Blazing The Trail For VTL In The Cloud
  • Data De-Dupe Gives VTL Customers More Options
  • Four Hundred Monitor, March 29
  • The Big Spending On IT Security Is Only Going To Get Bigger
  • IBM Tweaks Some Power Systems Prices Down, Others Up
  • Disaster Recovery: From OS/400 V5R3 To IBM i 7.4 In 36 Hours
  • The Disconnect In Modernization Planning And Execution
  • Superior Support: One Of The Reasons You Pay The Power Systems Premium
  • IBM i PTF Guide, Volume 25, Number 13

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2023 IT Jungle