mnlight has asked for the wisdom of the Perl Monks concerning the following question:

I am getting this error

syntax error at line 200, near "sub add_login"
Can't use global @_ in "my" line 202, near "= @_"
syntax error at line 227, near "}"
had compilation errors.

I can not find anything wrong with this code. Maybe a second set of eyes will help.
This is the call to the sub
add_login(\$dbhCurrent, $usrname, $first, $last, $passwd, $fncgrp); This is the sub
sub add_login{ Line 202 my ($dbhCurrent, $usrname, $first, $last, $passwd, $fncgrp) = + @_; my $full_last = $last . " SHPS"; my $sql = "sp_addlogin \'$usrname\', \'$passwd\', \'APPMASTER\'"; $$dbhCurrent->do($sql) or $app->log($WARN,"Can't do SQL statement [ $sql ] :: $DBI::errst +r"); $app->use_database($dbhCurrent, "$DB"); $sql = "exec stored_proc USR_ID"; $$dbhCurrent->do($sql) or $app->log($WARN,"Can't do SQL statement [ $sql ] :: $DBI::e +rrstr"); $sql = "declare \@usrid int, \@sysusrid int " . "select \@sysusrid = suser_id\(\'$usrname\'\) " . "select \@usrid = $IDVALUE from $ID " . "where $IDNAME = \'USR_ID\' " . "insert into APPUSR (APP_CD, USR_ID, USRNAME, USRFNAME, USRLNAM +E, FNCGRP_CD, SYSUSR_ID) " . "values (\'A\', \@usrid, \'$usrname\', \'$first\', \'$full_last +\', $fncgrp, \@sysusrid)"; $$dbhCurrent->do($sql) or $app->log($FATAL,"Can't do SQL statement [ $sql ] :: $DBI:: +errstr"); line 227 }
Line 227 is the curly bracket that completes the sub

Replies are listed 'Best First'.
Re: can't use global @_in "my"
by Jenda (Abbot) on Jul 31, 2007 at 20:33 UTC
    $sql = "declare \@usrid int, \@sysusrid int " . "select \@sysusrid = suser_id\(\'$usrname\'\) " . "select \@usrid = $IDVALUE from $ID " . "where $IDNAME = \'USR_ID\' " . "insert into APPUSR (APP_CD, USR_ID, USRNAME, USRFNAME, USRLNAM +E, FNCGRP_CD, SYSUSR_ID) " . "values (\'A\', \@usrid, \'$usrname\', \'$first\', \'$full_last +\', $fncgrp, \@sysusrid)";

    Please don't! This code is hard to read and dangerous!

    First, this is Perl, not Visual Basic or some other language with restricted string literals. You can write this much more readably. And actually even if you kept using doublequotes you do not need to escape singlequotes. "d\'Artagnan" is equivalent to "d'Artagnan". You could write the code like this:

    $sql = qq{ declare \@usrid int, \@sysusrid int select \@sysusrid = suser_id('$usrname') select \@usrid = $IDVALUE from $ID where $IDNAME = 'USR_ID' insert into APPUSR (APP_CD, USR_ID, USRNAME, USRFNAME, USRLNAME, FNC +GRP_CD, SYSUSR_ID) values ('A', \@usrid, '$usrname', '$first', '$full_last', $fncgrp, \ +@sysusrid) };
    Easier on the eyes, isn't it?

    In either case it's dangerous! Guess what happens if someone claims his username is "d'Artagnan"? Or maybe "') delete from APPUSR; select length('gotcha" ?

    USE placeholders!

    my $sth = $$dbhCurrent->prepare( qq{ declare \@usrid int, \@sysusrid int select \@sysusrid = suser_id(?) select \@usrid = $IDVALUE from $ID where $IDNAME = 'USR_ID' insert into APPUSR (APP_CD, USR_ID, USRNAME, USRFNAME, USRLNAME, FNC +GRP_CD, SYSUSR_ID) " . values ('A', \@usrid, ?, ?, ?, ?, \@sysusrid) }; $sth->execute( $usrname, $usrname, $first, $full_last, $fncgrp);
    Your use of $IDVALUE and $ID looks suspicious too, but those two cannot be replaced by placeholders. I do hope they are comming from someplace safe!

      Something to note - Chris is using Sybase where placeholders are aleged to come at a significant memory cost. You're frequently better off using $dbh->quote() and interpolating the escaped values.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        That's strange. under normal circumstances placeholders are much more efficient, especially if you reuse the statement handle returned by $dbh->prepare() and run the query many times. Do you have any links to this problem?

        In case you need to use $dbh->quote() it's possible to use Interpolation to make the syntax nicer:

        use Interpolation "'" => sub {"'".$dbh->quote($_[0])}; #... $sql = qq{ declare \@usrid int, \@sysusrid int select \@sysusrid = suser_id($'{$usrname}') select \@usrid = $IDVALUE from $ID where $IDNAME = 'USR_ID' insert into APPUSR (APP_CD, USR_ID, USRNAME, USRFNAME, USRLNAME, FNCGRP_CD, SYSUSR_ID) values ('A', \@usrid, $'{$usrname}', $'{$first}', $'{$full_last}', $fncgrp, \@sysusrid) };
      In this particular case you can't use placeholders with Sybase, because the request includes multiple statements in a single batch.

      It's probably possible to recode this to avoid multiple statements, however, and thus allow placeholders to be used.

      Michael

Re: can't use global @_in "my"
by FunkyMonk (Bishop) on Jul 31, 2007 at 19:30 UTC

    I'd look to what occurs before sub add_login{. Once perl finds a syntax error, all bets are off. So I would not take any notice of the "@_" error until you fix your syntax error.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: can't use global @_in "my"
by naikonta (Curate) on Aug 01, 2007 at 01:32 UTC
    I can't count how many times I've been hit by this. The fact that line 227 is a closing curly bracket usually almost always indicates that you have problem with parentheses/bracket matching. Check before line 202 upward, since line 202 is fine.

    One way I use to find the exact line of error is by consequetively putting die "OK" line between lines or blocks of code.


    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

      I fail to see how adding die statements would help find a *compile* error. BEGIN { die } might help, but for this type of problem, I usually remove entire chunks from the file until perl -c doesn't find the error. The last thing removed contains the error. Re-add smaller bits until the error comes back if the chunk was too big.
        You are right, ikegami. My second paragraph has nothing to do with the original problem. It's the technical I use for runtime error. Thanks for reminding me :-)

        Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: can't use global @_in "my"
by Old_Gray_Bear (Bishop) on Jul 31, 2007 at 19:40 UTC
    I'd need to see a little bit more of the code, but it sounds like you have a typo in the lines preceding line 200. My first bet would be a missing/extra quote somewhere.

    ----
    I Go Back to Sleep, Now.

    OGB

      My first bet would be a missing/extra quote somewhere.

      ... could be an extraneous opening parenthesis.

      #!/usr/bin/perl ({ sub add_login{ my ($var) = @_; #... } }

      At least, this produces a rather similar error:

      $ perl -c <629906.pl syntax error at - line 5, near "sub add_login" Can't use global @_ in "my" at - line 7, near "= @_" - had compilation errors.
Re: can't use global @_in "my"
by Argel (Prior) on Aug 01, 2007 at 00:17 UTC
    As others have said, look at the code preceeding the error. Likely you are missing a comma, semicolon, or anything that comes in pairs such as quotes, braces, etc..