Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

DBD::ODBC not support

by Bheema_Tyco (Novice)
on May 12, 2010 at 04:51 UTC ( [id://839531]=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks here is my question

I am writing query to update the table in my DB it is like thid

my $SQL = "UPDATE kcrei_batch_job_history SET rows_added = $_[1], status = 'C', stop_datetime = getdate(), stop_tran_seq_nbr = $hdr_tran_seq_nbr, elapsed_time_hh = datediff(hh, convert(dat +etime,$loader_start_time), getdate()) elapsed_time_mm = datediff(mi, convert(date +time,$loader_start_time), getdate()), elapsed_time_ss = datediff(ss, convert(dat +etime,$loader_start_time), getdate()) WHERE master_job_no = $master_job_no AND master_job_sub_no = $_[0]";

when i prepare this statement it is giving error like this

DBD::ODBC does not yet support binding a named parameter more than once

So to overcome this i wrote another query like as following, which is written by somebody else and i followed the same thing then its working fine

my @f = (localtime)[0..5]; my $stop_time = sprintf "%d-%02d-%02d %02d:%02d:%02d", $f[5]+1900 +, $f[4]+1, $f[3], $f[2], $f[1], $f[0]; Compute the elapsed time in hours, minutes and seconds. my $elapsed_time_ss = sprintf "%02d", timeDiff($loader_start_time +, $stop_time); my $elapsed_time_mm = sprintf "%02d", $elapsed_time_ss / 60; my $elapsed_time_hh = sprintf "%02d", $elapsed_time_ss / 3600; $stop_time .= ".000"; my $SQL = "UPDATE kcrei_batch_job_history SET rows_added = $_[1], status = 'C', stop_datetime = getdate(), stop_tran_seq_nbr = $hdr_tran_seq_nbr, elapsed_time_hh = $elapsed_time_hh, elapsed_time_mm = $elapsed_time_mm, elapsed_time_ss = $elapsed_time_ss WHERE master_job_no = $master_job_no AND master_job_sub_no = $_[0]";

here i am using timediff() function which is like this

############################################ # Function: TimeDiff ############################################ # param1 is the 'from' DateTime as 'YYYY-MM-DD HH:MM:SS' 24-hour clock # param2 is the 'to' Date as 'YYYY-MM-DD HH:MM:SS' 24 hour-clock # returns time difference in seconds sub timeDiff { my (@fromDT, @toDT); my (@fromT, @toT); my ($fromTM, $toTM); if(!defined($_[0]) || !defined($_[1])){ return(1); } @fromDT = split(/ /,$_[0]); @toDT = split(/ /,$_[1]); @fromT = split(/:/,$fromDT[1]); @toT = split(/:/,$toDT[1]); $fromTM = ($fromT[0] * 3600) + ($fromT[1] * 60) + $fromT[2]; $toTM = ($toT[0] * 3600) + ($toT[1] * 60) + $toT[2]; # If fromDT is different than toDT we make the assumption that eit +her the data is corrupt or the transaction ran over midnight if($fromDT[0] ne $toDT[0]){ my @fromDate = split(/-/,$fromDT[0]); my @toDate = split(/-/,$toDT[0]); if( ($fromDate[0] eq $toDate[0]) && ($fromDate[1] eq $toDate[1 +]) && ( ($toDate[2] - $fromDate[2]) == 1) ) { $toTM += (24 * 3600); } else { return; } } if(($toTM - $fromTM) == 0){ return(1); } return($toTM - $fromTM); }

can anybody tell me what was the problem and how it is resolved

because i am not getting anything

thanks

Replies are listed 'Best First'.
Re: DBD::ODBC not support
by mje (Curate) on May 12, 2010 at 10:08 UTC

    You are interpolating scalars containing ':' into your SQL and ':' is the introducer for named parameters. As a result DBD::ODBC thinks your SQL contains some named parameters and obviously some of those :xxx strings occur more than once. If you are not using named parameters (which you do not appear to be) and for some strange reason cannot use placeholders for the parameters you need to look at setting odbc_ignore_named_placeholders. However, I would just use bound parameters if I were you - much safer.

      i am running query like this

      my $SQL = "UPDATE kcrei_batch_job_history SET rows_added = ?, status = 'C', stop_datetime = getdate(), stop_tran_seq_nbr = ?, elapsed_time_hh = datediff(hh, convert(dat +etime,?), getdate()), elapsed_time_mm = datediff(mi, convert(dat +etime,?), getdate()), elapsed_time_ss = datediff(ss, convert(dat +etime,?), getdate()) WHERE master_job_no = ? AND master_job_sub_no = ?";
      my $sth = $dbh->prepare( $SQL ) or die "Couldn't prepare statement: " . $dbh->errstr; eval{ $sth->execute($_[1], $hdr_tran_seq_nbr, $loader_start_time, $loader_start_time, $loader_start_time, $master_job_no, $_[0] ); $sth->finish(); }; if( $@ ) { outputErrorMessage( "$@" ); outputErrorMessage( "$sth->{Statement}" ); }

      hi mje in this way i am running my query

        But what are the values of the parameters passed to execute?

      I have been trying to understand this for some time now. The ':' in the strings I was using for time parameters was in fact the problem.

      my $stime = '2010-01-01 00:00:00' my $qstring = qq{select * from mytable where start > $stime return};

      which returned the error "DBD::ODBC does not yet support binding a named parameter more than once". After reading this, I made things work by (abbreviatedj example)...

      my $stime = '2010-01-01 00:00:00' my $qstring = qq{select * from mytable where start > '$stime' return};

      ..which made all work just fine. Apparently those ':' create the problem.

      Thanks for pointing that out!

      Just goes to show; elephants don't bite, mosquitoes do!

      • ...the majority is always wrong, and always the last to know about it...
      • The Spice must flow...
      • ..by my will, and by will alone.. I set my mind in motion

        In DBI, the : introduces a named parameter into the SQL. The convention in the ODBC world is ? introduces a parameter but as DBI dictates :my_param is also valid DBD::ODBC has to parse the SQL to check for named parameters. If you create SQL containing an unquoted : it looks like a parameter. In your first example this is exactly what you did and because it was 00:00:00 it looks like you have 2 named parameters called "00". DBD::ODBC does not support binding the same named parameter more than once (Using the same placeholder more than once) and hence the message you got.

        If you absolutely have to include a string in your SQL instead of using a parameter marker (?) and binding the parameter you need to quote it and DBI has a quote method for just that (don't just use single quotes as it can differ between SQL engines).

        You can stop DBD::ODBC looking for named parameters by setting odbc_ignore_named_placeholders. In fact, I only wish the default could be this as it wastes time parsing the SQL if you are not using named parameters but DBI says it has to support them.

Re: DBD::ODBC not support
by ikegami (Patriarch) on May 12, 2010 at 05:32 UTC
    You didn't properly turn the contents of $loader_start_time into a literal. The easiest solution is to use placeholders:
    my $sth = $dbh->prepare(' UPDATE kcrei_batch_job_history SET rows_added = ?, status = 'C', stop_datetime = getdate(), stop_tran_seq_nbr = ?, elapsed_time_hh = datediff(hh, convert(datetime,?), getdate +()), elapsed_time_mm = datediff(mi, convert(datetime,?), getdate +()), elapsed_time_ss = datediff(ss, convert(datetime,?), getdate +()) WHERE master_job_no = ? AND master_job_sub_no = ? '); $sth->execute( $_[1], $hdr_tran_seq_nbr, $loader_start_time, $loader_start_time, $loader_start_time, $master_job_no $_[0], );

      Hi iskegami i had made the changes wat you have told

      but its giving error like this

      Revision : 1 Wed May 12 12:32:13 2010 DBD::ODBC::st execute failed: MicrosoftODBC SQL Server DriverInvalid character value for cast specification (SQL-22018) at D:\Bheema\kc_tlog_loaderSQL.pl line 997.

      Thanks

        I haven't done much SQL, and I haven't dealt with passing dates. Perhaps you need to specify the type of the argument.
        use DBI qw( :sql_types ); my $sth = $dbh->prepare(' ... '); $sth->bind_param(1, $_[1]); $sth->bind_param(2, $hdr_tran_seq_nbr); $sth->bind_param(3, $loader_start_time, SQL_DATETIME); $sth->bind_param(4, $loader_start_time, SQL_DATETIME); $sth->bind_param(5, $loader_start_time, SQL_DATETIME); $sth->bind_param(6, $master_job_no); $sth->bind_param(7, $_[0]); $sth->execute();

        Can we see the SQL you are running now, the way you've bound the parameters and the values of the parameters?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://839531]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2024-04-25 11:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found