String manipulation 101



  • This is how you build an SQL INSERT statement:

    cols = "<132 char. long hardcoded string>";
    vals = new StringBuilder("(" + <54 char. long expression> 
        + ", " + <same 54 char. long expression>
        + ", " + <35 char. long expression> // <82 char. long comment>
        + ", " + <92 char. long expression with embedded 24 char. long block comment> 
        + ", " + <63 char. long expression>
        + ", " + <61 char. long expression>
        + ", " + <60 char. long expression>
        + ", " + <74 char. long expression>
        + ", " + <66 char. long expression>
        + ", " + <57 char. long expression>
        + ", " + <66 char. long expression>
        + ", " + <111 char. long expression>
        + ", " + <74 char. long expression>
        + ", " + <60 char. long expression>
        + ", 0)");
    sql = "INSERT INTO " + tableName + " " + cols + " " + vals.ToString();
    

     

    Also, seen elsewhere:

    string tableAliasColName = String.Join(".", new string[]] { tableAlias, colName };

     

    And of course, who can forget:

    function int FromString(object myval)
    {
        if (myval == null)
            return 0;
        else if (myval is int)
            return (int)myval;
        else if (myVal is string)
        {
            if (myVal.Equals(""))
                return 0;
            else
            {
                int outVal = 0;
                if (int.TryParse(myval.ToString(), out outVal))
                    return int.Parse(myVal.ToString());
                else
                    return 0;
            }
        }
        return 0;
    }
    


  • "But...but...StringBuilder is faster than simple concatenation!"



  • Help, my palm is stuck to my face!

    I've never coded in Java/C#/whatever but even I know that this is not how you use StringBuilder.



  • @derula said:

    Help, my palm is stuck to my face!

    I've never coded in Java/C#/whatever but even I know that this is not how you use StringBuilder.

    This a fine example on using the right tool for the job very wrongly.

    We should find this person and shoot it, slowly



  • @serguey123 said:

    shoot it, slowly

    This should be interesting.



  • @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?

  • ♿ (Parody)

    @serguey123 said:

    @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?

    I had a similar reaction to shooting something slowly. Are you giving it a sporting chance by pulling the trigger slowly? Using slow projectiles? Kill it, slowly, makes sense. Shooting slowly, not so much.



  • @boomzilla said:

    @serguey123 said:

    @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?

    I had a similar reaction to shooting something slowly. Are you giving it a sporting chance by pulling the trigger slowly? Using slow projectiles? Kill it, slowly, makes sense. Shooting slowly, not so much.
     

    Shooting can be things other than firearms.  Obviously he meant something like shoot basketballs at them, throwing slowly, until they are beaten to death.



  • @locallunatic said:

    @boomzilla said:

    @serguey123 said:

    @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?


    I had a similar reaction to shooting something slowly. Are you giving it a sporting chance by pulling the trigger slowly? Using slow projectiles? Kill it, slowly, makes sense. Shooting slowly, not so much.
     

    Shooting can be things other than firearms.  Obviously he meant something like shoot basketballs at them, throwing slowly, until they are beaten to death.

    Or it could be with firearms after all. Shooting him in the foot first, then the knee, maybe the shoulder, ya know...?



  • @derula said:

    @locallunatic said:

    @boomzilla said:

    @serguey123 said:

    @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?

    I had a similar reaction to shooting something slowly. Are you giving it a sporting chance by pulling the trigger slowly? Using slow projectiles? Kill it, slowly, makes sense. Shooting slowly, not so much.
     

    Shooting can be things other than firearms.  Obviously he meant something like shoot basketballs at them, throwing slowly, until they are beaten to death.

    Or it could be with firearms after all. Shooting him in the foot first, then the knee, maybe the shoulder, ya know...?

     

    Or using specially loads, like subsonic rounds.


  • ♿ (Parody)

    I think the basketball approach makes the most sense.



  • Matrix bullets?

    Once I saw some SQL concatenation in some coworkers' code base, it looked about like this:

    
    public static final String SOME_SQL_LOOKUP = new StringBuffer()
        .append("SELECT blahblah, blah")
        .append("FROM tbldurp")
        .append("WHERE foo = ?")
        .append("AND bar = 'chirp'")
        .toString();
    

    I was already criticizing them for some serious coding bugs, so I didn't feel like being nitpicky in addition. Not nearly as bad as OP, but whoever wrote that clearly doesn't understand the language.

    1) As it is declared public static final, SOME_SQL_LOOKUP is a compile-time constant. Concatenating literal strings is also done at compile time* so removing all the StringBuffer appends and replacing them with simple literal + concatenations would be better in this case.
    2) A StringBuffer instead of a StringBuilder? Uuuugh...
    3) This can trivially written in one line anyway, although I'll grant them some aesthetic leeway. But then why clutter it up with those append()s? Oh right, because that's what they were told to do and they don't understand why.

    These were also the same guys who used a simplified hungarian notation in Java. To them, this meant that every variable name except for Strings and primitives was prefixed with an o ... because everything is an Object.... yup...



  • @locallunatic said:

    @derula said:

    @locallunatic said:

    @boomzilla said:

    @serguey123 said:

    @derula said:

    @serguey123 said:
    shoot it, slowly
    This should be interesting.

    Why?

    I had a similar reaction to shooting something slowly. Are you giving it a sporting chance by pulling the trigger slowly? Using slow projectiles? Kill it, slowly, makes sense. Shooting slowly, not so much.
     

    Shooting can be things other than firearms.  Obviously he meant something like shoot basketballs at them, throwing slowly, until they are beaten to death.

    Or it could be with firearms after all. Shooting him in the foot first, then the knee, maybe the shoulder, ya know...?
     

    Or using specially loads, like subsonic rounds.

    It seemed I was not wrong after all. ok

    Other ways to do this

    1. Use a time bubble where time is slowed
    2. Use a drug that enhance the perception of time
    3. Use a high density medium, like water to make the proyectile slower
    4. Or perhaps I meant that the interval between shooting him/her in different places should be large for maximum psychological effect


  • @Xyro said:

    These were also the same guys who used a simplified hungarian notation in Java. To them, this meant that every variable name except for Strings and primitives was prefixed with an o ... because everything is an Object.... yup...
     

    I also touch things done like this, hopefully you shot the coworker slowly with basketballs.


  • ♿ (Parody)

    @Xyro said:

    Matrix bullets?

    Once I saw some SQL concatenation in some coworkers' code base, it looked about like this:

    3) This can trivially written in one line anyway, although I'll grant them some aesthetic leeway. But then why clutter it up with those append()s? Oh right, because that's what they were told to do and they don't understand why.

    And let's be honest. If string concatenation of a SQL statement is causing a performance hit, you've got bigger problems than that.


  • @locallunatic said:

    I also touch things done like this, hopefully you shot the coworker slowly with basketballs.

    I tried to, but the basketballs refused to shoot them on grounds of moral issues. So I shot the basketballs instead. Nothing but net!!


  • Garbage Person

    @toth said:

    "But...but...StringBuilder is faster than simple concatenation!"
    Except when it's not.

     In .net, at least, the compiler will take up to 4 +'s and turn them into a single call to String.Concat(). String.Concat(String, String, String, String) is significantly faster than the equivalent stringbuilder. 

    Now if MS will just teach the compiler to do stringbuilders, we can get rid of yet another piece of apocrypha.



  • @boomzilla said:

    And let's be honest. If string concatenation of a SQL statement is causing a performance hit, you've got bigger problems than that.
    No, it means the rest of your system is extremely performant!

     

    BTW, for those who may not have seen much of a WTF on the latter piece of code (it's not as bad as the former anyway):

    int outVal = 0;
    if (int.TryParse(myval.ToString(), out outVal))
        return int.Parse(myVal.ToString());
    else
        return 0;
    It just so happens that int.TryParse() and int.Parse() behave exactly the same, except TryParse will set outVal to zero and return false if the string fails to parse as a number, while Parse will throw an exception. So that code is equivalent to just calling TryParse and returning outVal.

     

    And while on the subject of exceptions: calling the constructor of an exception inside of a catch block, solely for the side-effect of logging, FTW.

     

     

     

    EDIT: let me clarify that:

    catch {
        new OurNiftyExceptionClass("An exception was thrown in method blah of class yuck!");
        throw;
    }


  • @Xyro said:

    Matrix bullets?

    Once I saw some SQL concatenation in some coworkers' code base, it looked about like this:

    
    public static final String SOME_SQL_LOOKUP = new StringBuffer()
        .append("SELECT blahblah, blah")
        .append("FROM tbldurp")
        .append("WHERE foo = ?")
        .append("AND bar = 'chirp'")
        .toString();
    

    I was already criticizing them for some serious coding bugs, so I didn't feel like being nitpicky in addition. Not nearly as bad as OP, but whoever wrote that clearly doesn't understand the language.

    1) As it is declared public static final, SOME_SQL_LOOKUP is a compile-time constant. Concatenating literal strings is also done at compile time* so removing all the StringBuffer appends and replacing them with simple literal + concatenations would be better in this case.
    2) A StringBuffer instead of a StringBuilder? Uuuugh...
    3) This can trivially written in one line anyway, although I'll grant them some aesthetic leeway. But then why clutter it up with those append()s? Oh right, because that's what they were told to do and they don't understand why.

    These were also the same guys who used a simplified hungarian notation in Java. To them, this meant that every variable name except for Strings and primitives was prefixed with an o ... because everything is an Object.... yup...

    Possibly the result of maintenance and concept migration.

    1. Probably started as a standard non-static variable built at run-time (a fairly common though inefficient paradigm).
    2. Probably originally written pre-Java 5, when StringBuilder wasn't available.
    3. Yes, the next round of code review the maintenance engineer calmly strips out the appends and makes it all one string, either by using "+" concatenation. Yes it could be written on one line, but I've had DBA's complain that the SQL then isn't formatted neatly on the page in the form it's presented here.

    I won't condone Hungarian notation, though. Apart from that, very much the sort of stuff I no longer have to maintain. No big deal.



  • @Zecc said:

    This is how you build an SQL INSERT statement:

    cols = "<132 char. long hardcoded string>";
    vals = new StringBuilder("(" + <54 char. long expression> 
        + ", " + <same 54 char. long expression>
        + ", " + <35 char. long expression> // <82 char. long comment>
        + ", " + <92 char. long expression with embedded 24 char. long block comment> 
        + ", " + <63 char. long expression>
        + ", " + <61 char. long expression>
        + ", " + <60 char. long expression>
        + ", " + <74 char. long expression>
        + ", " + <66 char. long expression>
        + ", " + <57 char. long expression>
        + ", " + <66 char. long expression>
        + ", " + <111 char. long expression>
        + ", " + <74 char. long expression>
        + ", " + <60 char. long expression>
        + ", 0)");
    sql = "INSERT INTO " + tableName + " " + cols + " " + vals.ToString();
    

     

    Also, seen elsewhere:

    string tableAliasColName = String.Join(".", new string[] { tableAlias, colName };

     

    And of course, who can forget:

    function int FromString(object myval)
    {
        if (myval == null)
            return 0;
        else if (myval is int)
            return (int)myval;
        else if (myVal is string)
        {
            if (myVal.Equals(""))
                return 0;
            else
            {
                int outVal = 0;
                if (int.TryParse(myval.ToString(), out outVal))
                    return int.Parse(myVal.ToString());
                else
                    return 0;
            }
        }
        return 0;
    }
    

    Hang on a minute, I recognise this pattern. You don't work for SBS do you?



  • @Weng said:

    @toth said:

    "But...but...StringBuilder is faster than simple concatenation!"
    Except when it's not.

     In .net, at least, the compiler will take up to 4 +'s and turn them into a single call to String.Concat(). String.Concat(String, String, String, String) is significantly faster than the equivalent stringbuilder. 

    Now if MS will just teach the compiler to do stringbuilders, we can get rid of yet another piece of apocrypha.

    whoosh


  • Considered Harmful

    @Zecc said:

    TryParse will set outVal to zero and return false if the string fails to parse as a number,

    This always bugged me a little. It seems like outVal should have been declared ref instead of out, so it could leave the previous value alone if parsing fails. I understand this means you'd have to initialize the variable before passing it in, but that's cleaner than storing the previous value in a temporary variable, checking for success, and restoring it if it fails.

    In the common case, you could just initialize your variable to the default, then TryParse, and not even need to check the return value, if it behaved this way.

    I'd also love a Nullable<int>.TryParse so I could write: var page = int?.TryParse( Request.QueryString[ "page" ] ) ?? 1;


  • Garbage Person

    @toth said:

    @Weng said:

    @toth said:

    "But...but...StringBuilder is faster than simple concatenation!"
    Except when it's not.

     In .net, at least, the compiler will take up to 4 +'s and turn them into a single call to String.Concat(). String.Concat(String, String, String, String) is significantly faster than the equivalent stringbuilder. 

    Now if MS will just teach the compiler to do stringbuilders, we can get rid of yet another piece of apocrypha.

    whoosh

    No, I got it. I'm just being a humorless fuck.



  • @Matt Westwood said:

    Hang on a minute, I recognise this pattern. You don't work for SBS do you?
    I don't work for any of the SBS' I'm presented with by Google.

    In particular, I don't work for Australia's SBS. The commute would be a bitch.


Log in to reply