Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

why did it do that?

Status
Not open for further replies.

1DMF

Programmer
Joined
Jan 18, 2005
Messages
8,795
Location
GB
this is more a puzzle than a required fix to a problem, I've solved the problem I think.

what I don't understand is why I didn't get an error and why it behaved the way it did.

Basically I have a sub which is passed a form it takes the data and inserts a new record into SQL.

Simple enough, the update SQL routine I hand rolled and you call it like this...
Code:
my $rec = &insSQL("Table","Column1,Column2,Column3","'Value1','Value2','Value3'");

prety basic really, the thing is i'd made a typo and forgot to put the & in front so it was ...
Code:
my $rec = insSQL("Table","Column1,Column2,Column3","'Value1','Value2','Value3'");

When the code ran, sometimes you'd submit the form and when the page refreshed it had inserted 2 records (a duplicate).

It didn't happen everytime but quite a lot and it took me ages to finally find the problem as I just couldn't see the missing &

I'm puzzled, why did the script not error? i'm used to calling subs by putting an & infront, but obviously it works without the & but why was it sometimes inserting 2 records.

what does 'subname(vars)' do different to '&subname(vars)'

can anyone shed some light on this please.




"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Strange. I never use the '&' sigil when calling subroutines. The differences between calling a subroutines with and without it are in the "perlsub" manpage (the bit you're lookin for starts with the text: 'A subroutine may be called using an explicit "&" prefix')
 
hey ishnid.

ok I've had a quick butchers, and found the info, I can't see what might be the problem, this shows...
To call subroutines:

NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current @_ visible to called subroutine.

if my standard way of doing things is &NAME(LIST); and this 'Circumvents prototypes' , what does that mean.

what are these 'prototypes' and could they be causing the difference?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok i did some googling and found , but whoa laddy, a bit heavy reading for a Friday morning.

But what i did decipher was it changes the way the @_ data is handled as it takes these prototypes into concideration, so maybe it was changing the way it took the @_ vars and somehow made the routine run twice.

ok , it hasn't solved my problem...... it's just added two records!!!!

here is the code , why is it adding two records?

Code:
#################
# ADD ITEM      #
#################
sub add_item {

&DSN("SSPL");

my (@ord,$inspur);
my $msg = "";

# check if order exists
@ord = &getSQL("Purchases","*","OrdID='$data{'ORDID'}'");

    # create order if not
if(!@ord){
    my $time = time;
    my @ukdate = &uk_date;
    my $rec = &insSQL("Purchases","OrdID,FirstName,LastName,Email,BuyerID,PayDate,
Purchase_Time","'$data{'ORDID'}','$data{'firstname'}','$data{'lastname'}',
'$data{'email'}','$data{'buyerid'}','$ukdate[0] $ukdate[1] GMT',$time");
    $msg .= "Order Added\\n\\n";
}

# Create Item
my $catno = $data{'catno'};
$catno =~ s/SSP//gi;
                
                # Check if Album
                if($catno =~ /A/){

                    # Strip album prefix
                    $catno =~ s/-A-//gi;
                    
                    # Get DB Record
                    my @alb = &getSQL("Albums","Artist,Title","CatNo=$catno");

                    # update Purchased_Items table with Album details
                    my $seller = ALBUMS_PRICE * SELLER_AMOUNT;

                    #escape title
                    $alb[0]{'Title'} =~ s/'/'/g;

                    my $sql = "'$data{'ORDID'}','$data{'catno'}','$alb[0]{'Artist'}','$alb[0]{'Title'}',
" . ALBUMS_PRICE . ",$seller,'SALE'";
                    $inspur = &insSQL("Purchased_Items","OrdID,CatNo,Artist,Title,Amount,Artist_Amount,
Status",$sql);

                    my $rec = &updSQL("Purchases","PayTotal=PayTotal+" . ALBUMS_PRICE .",NoItems=NoItems+1","OrdID='$data{'ORDID'}'");

                    #update seller stats
                    $rec = &updSQL("Seller_Stats","Albums=Albums+1","Artist='$alb[0]{'Artist'}'");

                }
                else{
                           
                    # Get DB Record
                    my @rec = &getSQL("Singles","Artist,Title","CatNo=$catno");                
                
                    # escape title
                    $rec[0]{'Title'} =~ s/'/'/g;
                    
                    # update Purchased_Items table
                    my $seller = SINGLES_PRICE * SELLER_AMOUNT;
                    my $sql = "'$data{'ORDID'}','$data{'catno'}','$rec[0]{'Artist'}','$rec[0]{'Title'}',
" . SINGLES_PRICE . ",$seller,'SALE'";
                    $inspur = &insSQL("Purchased_Items","OrdID,CatNo,Artist,Title,Amount,Artist_Amount,
Status",$sql);  

                    # Upate purchases
                    my $amt = $ord[0]{'PayTotal'} + SINGLES_PRICE;
                    my $noitems = $ord[0]{'NoItems'} + 1;

                    my $rec = &updSQL("Purchases","PayTotal=PayTotal+" . SINGLES_PRICE . ",NoItems=NoItems+1","OrdID='$data{'ORDID'}'");

                    #update seller stats
                    $rec = &updSQL("Seller_Stats","Singles=Singles+1","Artist='$rec[0]{'Artist'}'");
                }


$msg .= "Item Added.\\n\\n";

&orders("$msg");
 
exit();

}

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok - ignore me i'm an idiot! , well I think (needs more testing before i can be certain i found the problem)!

It was nothing to do with the perl code, the missing & put me on a wild goose chase, but you knew that didn't you ishnid ;-)

It was the HTML form and JS, I had a submit button with action = my JS code and onclick = my JS code.

I beleive the form data was being sent twice, and depending on how quick the server was responding depended on whether it managed to run the perl script twice or not.

The JS was being fired twice and the way I call the perl script is via document.location.href = url+vars; (not submitting the form)

I'm still unsure how calling it twice enabled it to change the browser location twice, it must have called the script so fast that perl ran and processed the call but before printing the HTML template to the browser, the JS called the script again and so inserted another record.

That will teach me to for using unorthadox form submission methods with JS.

oh well, won't do that again in a hurry!

pretty crazy when you think about how the timings had to be spot on for it to happen, which is why I was getting sporadic duplicate records running the same code again and again.

Well let's hope that was the problem and now it's fixed :-D

regards
1DMF





"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top