Thread: Oracle OCI programming returning null value into define variable

  1. #1
    Registered User
    Join Date
    Dec 2001
    Posts
    40

    Oracle OCI programming returning null value into define variable

    Hi,
    I have a query that returns a value into a define variable, but if there is no value in the database for that field it inserts null. On Solaris this works fine, but I have migrated my code to Red Hat and it is behaving differently. The code is:


    Code:
        if ( RtrnValue == OCI_NO_DATA )
        {
            return (FALSE);
        }
        else if ( RtrnValue == OCI_SUCCESS )
        {
    
            switch (Migrated)
            {
                case 'Y':
                    /* This cli is marked as migrated, so convert it as normal */
                        strcpy( CliRec->AccountNumber, Account );
                    return (TRUE);
                case 'N':
                    /* I dont think that this will happen, but it potentially could 
                    ** If it does then update the cli, set the migrated field to yes */
                default:
                    /* The value should come through as null if the migrated field is not set
                    ** hopefully this will catch null values */
                    strcpy( CliRec->AccountNumber, Account );
                    return (FALSE);
            }
    
        }
        else if ( Migrated == NULL )
        {
            strcpy( CliRec->AccountNumber, Account );
            return (FALSE);
        }
        else
        {
            check_err( OraErrorHandlePtr, RtrnValue);
            return (FALSE);
        }
    What predominently happens is the code falls through to the:
    else if Migrated == NULL
    statement and executes that statement and returns FALSE, however on Red Hat it does not recognise that Migrated == NULL and falls through to the check_err statement which then prints out the message:
    ERROR - ORA-01405: fetched column value is NULL
    So the value is NULL but as far as Red Hat is considered it isnt. Any ideas anybody?
    Thanks
    Peter

  2. #2
    Registered User
    Join Date
    Dec 2001
    Posts
    40
    I think I have a workaround. I have added the nvl function call into the select statement so that it returns a known value whenever it would return a NULL. Hopefully this will sort it out.
    Still cant figure out why the test for NULL that works on Solaris does not work on Red Hat.

  3. #3
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    Your short code snippet doesn't provide enough clues as to why "Migrated" is not NULL when you expect it to be. You don't assign to it anywhere in the code you posted. The problem is in some code you left out.

    It might help to print out "Migrated" so you can see what value it actually has.

    By the way, "Migrated" is not a pointer, so it's bad style to compare it with NULL. NULL is meant to be used only with pointers. If you want to compare a character with ASCII NUL, use '\0' instead.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by christop View Post
    If you want to compare a character with ASCII NUL, use '\0' instead.
    Or just simply zero. No need to waste the extra characters.

    Or you could go one step further:

    Code:
    else if ( !Migrated )
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    Quote Originally Posted by Elkvis View Post
    Or just simply zero. No need to waste the extra characters.

    Or you could go one step further:

    Code:
    else if ( !Migrated )
    By that logic, we don't even need NULL either--just use 0:
    Code:
    int *p = 0;
    Clear as day!

    What you call "wast[ing] the extra characters", I call "making the programmer's intent clear". Saving characters in source code should not be a primary goal. Using "!Migrated" implies that Migrated is a Boolean value while it's actually a character. So compare a character with another character, like '\0'.

    On the other hand, there's no problem with using expressions like "!ptr", where ptr is a pointer, because that's a very common idiom in C for checking if a pointer is NULL.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by christop View Post
    Saving characters in source code should not be a primary goal.
    But every C programmer should know that '\0' is the same as integer zero. The international C standard literally says so.

    Quote Originally Posted by christop View Post
    Using "!Migrated" implies that Migrated is a Boolean value while it's actually a character.
    No, it implies that Migrated is something that converts to boolean, which all integer types, including char, do. Again, the C standard explicitly says this. This is basic C knowledge that every C programmer should have.

    Quote Originally Posted by christop View Post
    On the other hand, there's no problem with using expressions like "!ptr", where ptr is a pointer, because that's a very common idiom in C for checking if a pointer is NULL.
    It's also the C idiom for checking if an integer type variable is zero. See above.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    I don't disagree with you that every C programmer should know those things; it can be very helpful for any programmer who has the misfortune of having to maintain any code that follows your style choices.

    My point is more about what a programmer should do, whereas your point seems more about what a programmer can do according to the C standards. I prefer to make my coworkers and my future self happy by making the intent of the code clear. A char, a short, an int, a long, and even a float or a double value can all be implicitly converted to a Boolean expression, but except for cases where the variable is intended to hold only Boolean values (true or false), it's much clearer not to treat them as Boolean. (C has had a true Boolean type for the past 16 years, so there's really no excuse to use anything but _Bool (or bool) for any variable that is intended to be used as a true Boolean anyway. The fact that "boolean" expressions return an int is a historical artifact that can largely be ignored--it's safe to store the result of any such expression in a _Bool variable.)

    You can do a lot of other weird yet legal things in C (heck, you can write your whole program on a single line to save all those extra newline characters!), but it doesn't mean it's a good idea to do so. See the IOCCC for good examples of taking the "what can I do?" idea to the extreme.

    Here's a relevant quote from a page by Steve Summit, author of the famous C FAQ site (emphasis mine):

    Quote Originally Posted by Steve Summit
    The authors make a good point about style: if valid is conceptually a Boolean variable (that is, it's an integer, but we only care about whether it's zero or nonzero, in other words, ``false'' or ``true''), then

    Code:
        if(valid)
    is a perfectly reasonable and readable condition. However, when values are not conceptually Boolean, I encourage you to make explicit comparisons against 0. For example, we could have expressed our average-taking code as

    Code:
        if(n && sum / n > 1)
    but I think it's clearer to be explicit and say

    Code:
        if(n != 0 && sum / n > 1)
    (However, many C programmers feel that expressions like

    Code:
        if(n && sum / n > 1)
    are ``more concise,'' so you will see them all the time and you should be able to read them.)
    I believe he is referring to the authors (Kernighan and Ritchie) of "The C Programming Language (Second Edition)" (again, emphasis mine):

    Since an if tests the numeric value of an expression, certain coding shortcuts are possible. The most obvious is writing

    Code:
    if (expression)
    instead of

    Code:
    if (expression != 0)
    Sometimes this is natural and clear; at other times it can be cryptic.
    Of course, all of this is subjective, and the compiler will accept a lot of code regardless of its quality, so I probably won't convince you either way on this issue of style.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by christop
    On the other hand, there's no problem with using expressions like "!ptr", where ptr is a pointer, because that's a very common idiom in C for checking if a pointer is NULL.
    Agreed, which is also why I prefer to write if (ptr) rather than if (ptr != NULL), i.e., I see the direct use of a pointer in a boolean context to be conventional. Contrast with an int n that is not meant to be a boolean: I find both if (n) and if (!n) to be awkward and would prefer if (n != 0) or if (n == 0).

    EDIT:
    Another point to consider in favour of not explicitly comparing pointers with a null pointer constant is that if (ptr) not only has a negative-tone natural language interpretation of "if ptr is not a null pointer", but also lends itself well to a positive-tone natural language interpretation of "if ptr points to an object/function", whereas if (ptr != NULL) tends to only convey the former (though strictly speaking the latter implies the former, but not the other way round, since pointers could be invalid).
    Last edited by laserlight; 06-17-2015 at 07:24 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    956
    Quote Originally Posted by laserlight View Post
    Another point to consider in favour of not explicitly comparing pointers with a null pointer constant is that if (ptr) not only has a negative-tone natural language interpretation of "if ptr is not a null pointer", but also lends itself well to a positive-tone natural language interpretation of "if ptr points to an object/function", whereas if (ptr != NULL) tends to only convey the former (though strictly speaking the latter implies the former, but not the other way round, since pointers could be invalid).
    I really like that: positive tones are preferable to negative tones.

    It's like in UI design, where it's a good idea to use positive verbiage rather than negative verbiage for checkboxes and similar design elements, such as "Enable this" or "Do that" as opposed to "Disable this" or "Don't do that".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to define string without null at the end!?
    By hyaku_ in forum C Programming
    Replies: 6
    Last Post: 11-22-2006, 06:11 AM
  2. CreateDIBSection() returning NULL
    By arjunajay in forum Windows Programming
    Replies: 5
    Last Post: 07-26-2006, 09:54 AM
  3. C++ Oracle database programming
    By enhancedmode in forum C++ Programming
    Replies: 1
    Last Post: 11-15-2004, 03:46 PM
  4. Replies: 1
    Last Post: 04-06-2003, 09:06 AM
  5. NULL Define - Why?
    By Davros in forum C++ Programming
    Replies: 22
    Last Post: 12-15-2002, 11:33 AM