simon.proctor has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to check if a date is null and then set a flag accordingly using CASE. The query works fine in Query Analyser and it works if I remove the CASE statement. However, this is what I get with the case included:
DBD::ODBC::st execute failed: [Microsoft][ODBC SQL Server Driver] Invalid character value for cast specification (SQL-22018)(DBD: st_execute/SQLExecute err=-1)
I split it over a few lines for readability.

I confess to being quite stuck. I suspect I need to change the default casting for my query based on it examining the date_completed column but its not something I could find on the web via google. Here is my query:
select ID, project_ID, title, details, DATEPART(dd, date_expected), DATEPART(mm, date_expected), DATEPART(yyyy, date_expected), DATEPART(dd, date_completed), DATEPART(mm, date_completed), DATEPART(yyyy,date_completed), is_complete = case when date_completed is null then 0 else 1 end from MILESTONES where ID = 1
Thanks in advance for any help, suggestions.

Simon

Replies are listed 'Best First'.
Re: SQL Server CAST problem using CASE with DBD::ODBC
by matija (Priest) on Mar 09, 2004 at 12:26 UTC
    Well, the SQL solution would be to do whatever needs to be done to satisfy the SQL on the other side. (What you're getting is an SQL error, not a Perl one, after all).

    The Perl solution would be to get rid of the cast, and simply test date_completed in Perl:

    $sth=$dbh->prepare(select ....); $sth->execute; $res=$sth->fetchrow_hashref; $$res{is_complete}=defined($$res_{date_completed});
Re: SQL Server CAST problem using CASE with DBD::ODBC (invisible)
by tye (Sage) on Mar 09, 2004 at 17:57 UTC

    Given "Invalid character value for cast specification" and that it works when not using Perl, I'd guess "\t" or "\r" is the problem. Seems unlikely. You should probably also dump (for example, using Data::Dumper) the string to make sure there aren't more unusual characters in there that you aren't seeing.

    - tye        

Re: SQL Server CAST problem using CASE with DBD::ODBC
by iburrell (Chaplain) on Mar 09, 2004 at 20:00 UTC
    To track down a cast error, you need to find where the type conversion is being done and where the invalid data is coming from. Conversion errors happen freqently when passing data from Perl, especially when Perl chooses the wrong type to send to the database. Unless there is more code that you aren't showing us, the code isn't passing parameters and this is not the problem.

    Since this is a static query, that Query Analyzer and Perl have different results is surprising. Try rewriting the SQL to eliminate the CASE, or use the other form of the CASE. CASE ... END AS is_complete is the same and might cause problems. Also, you might want to parse the date in Perl.

Re: SQL Server CAST problem using CASE with DBD::ODBC
by EdwardG (Vicar) on Mar 10, 2004 at 18:07 UTC

    With what you've described, I can't see what would cause your problem. I tried it.

    (Since you didn't provide any schema or sample data I invented some.)

    -- T-SQL create table milestones ( [id] int not null, project_ID char(1) null, title char(1), details char(1) null, date_expected smalldatetime null, date_completed smalldatetime null ) go insert into milestones values (1,'a','a','a','2004-01-01', '2004-01-01 +') insert into milestones values (1,'b','a','a','2004-01-02', '2002-01-01 +') insert into milestones values (1,'c','a','a','2004-02-10', null) insert into milestones values (1,'d','a','a', null, null) insert into milestones values (1,'e','a','a','2004-11-11', null) go select * from milestones go -- Milestones now contains - id project_ID title details date_expected date_compl +eted ----------- ---------- ----- ------- ---------------------- ---------- +--------- 1 a a a 2004-01-01 00:00:00 2004-01-01 + 00:00:00 1 b a a 2004-01-02 00:00:00 2002-01-01 + 00:00:00 1 c a a 2004-02-10 00:00:00 NULL 1 d a a NULL NULL 1 e a a 2004-11-11 00:00:00 NULL (5 row(s) affected) # Perl code use strict; use warnings; use DBI; my $dbh = DBI->connect("dbi:ODBC:driver=SQL Server;database=pubs;serve +r=(local)", 'sa', 'mypassword') or die "can't connect"; my $q = qq{ select ID, project_ID, title, details, DATEPART(dd, date_expected), DATEPART(mm, date_expected), DATEPART(yyyy, date_expected), DATEPART(dd, date_completed), DATEPART(mm, date_completed), DATEPART(yyyy,date_completed), is_complete = case when date_completed is null then 0 else 1 end from MILESTONES where ID = 1 }; my $sth= $dbh->prepare($q); $sth->execute; while (my @row = $sth->fetchrow_array) { $_ ||= 'NULL' for @row; print "@row\n"; } $sth->finish; $dbh->disconnect; __END__ d:\tmp>Test.pl 1 a a a 1 1 2004 1 1 2004 1 1 b a a 2 1 2004 1 1 2002 1 1 c a a 10 2 2004 NULL NULL NULL NULL 1 d a a NULL NULL NULL NULL NULL NULL NULL 1 e a a 11 11 2004 NULL NULL NULL NULL
A reply falls below the community's threshold of quality. You may see it by logging in.