2010-09-29 25 views
2

Je crée un rapport dans Reporting Services 2005, où les données sont extraites d'une base de données Informix. La connexion à la base de données est déclarée via ODBC. Voici la version simplifiée de la requête:Informix - '||' l'opérateur ne fonctionne pas sur la connexion ODBC

select 
    prodtype, 
    familynum, 
    family, 
    sum(invested) invested, 
    month(recevdate) month, 
    year(recevdate) year, 
    day(recevdate) day, 
    'All Year' const 
from 
    sales_product 
where 
    (region not in ('15876','15852')) and 
    (prodtype in ('4','7','50','1')) and 
    (recevdate >= ('01/01/' || (year(?) - 1))) and 
    (recevdate <= Date('12/31/' || (year(?) - 1))) 
group by 1,2,3,5,6,7 

Si vous regardez la clause where, vous verrez que je prends l'année à partir du paramètre, puis en ajoutant à un mois de chaîne et jour. Le problème ici est que le '||' L'opérateur travaille directement dans Informix, mais pas sur ODBC. Lorsque j'exécute cette requête, j'obtiens une erreur de syntaxe. Existe-t-il un autre moyen de concaténer deux chaînes?

Répondre

1

Dans les circonstances, je pense que le meilleur choix est d'utiliser la fonction au lieu de concaténation de chaînes MDY():

SELECT prodtype, familynum, family, 
     sum(invested) invested, 
     month(recevdate) month, 
     year(recevdate) year, 
     day(recevdate) day, 
     'All Year' const 
    FROM sales_product 
WHERE (region NOT IN ('15876','15852')) 
    AND (prodtype in ('4','7','50','1')) 
    AND (recevdate BETWEEN MDY(1, 1, YEAR(?) - 1) AND MDY(12, 31, YEAR(?) - 1)) 
GROUP BY 1,2,3,5,6,7 

Je suppose que le? La valeur d'espace réservé est une valeur DATE complète, la fonction YEAR est donc nécessaire. Vous pouvez simplifier la requête si vous passez dans le numéro de l'année exacte que vous êtes intéressé par:

SELECT prodtype, familynum, family, 
     sum(invested) invested, 
     month(recevdate) month, 
     year(recevdate) year, 
     day(recevdate) day, 
     'All Year' const 
    FROM sales_product 
WHERE (region NOT IN ('15876','15852')) 
    AND (prodtype in ('4','7','50','1')) 
    AND (recevdate BETWEEN MDY(1, 1, ?) AND MDY(12, 31, ?)) 
GROUP BY 1,2,3,5,6,7 

Quant à savoir pourquoi la concaténation de chaîne est « un échec » ... ce n'est pas clair. Cependant, l'un des avantages de la fonction MDY() est que ses arguments ne sont pas ambigus, indépendamment des paramètres régionaux (paramètres régionaux du client et du serveur). Une cause possible de votre problème est que le format de date défini par (ou non défini) par Reporting Services est différent de celui que vous indiquez dans votre requête - et différent de celui qui est défini lorsque vous exécutez la requête directement. C'est une supposition - une hypothèse plausible mais nullement définitive. Une autre possibilité est que vous ne transmettez la date de référence qu'une seule fois, même si elle est utilisée deux fois dans la clause condition de la requête. Si nous avions le message d'erreur donné, nous pourrions être en mesure de faire une meilleure estimation de la source du problème.

+0

C'est génial ... et le code est beaucoup plus propre Merci – Skadoosh

0

Essayez d'utiliser + pour concat ou peut-être quelque chose comme strcat()

+0

J'ai essayé d'utiliser +, mais cela m'a donné un 'Caractère de l'erreur de conversation numérique'. En utilisant 'strcat' je reçois un ne peut pas résoudre l'erreur strcat. – Skadoosh

+0

Non - pas dans Informix. –

0

Je pense avoir trouvé une solution à la question ... Au lieu d'utiliser || opérateur j'ai pensé utiliser la fonction Remplacer. Donc, au lieu de (recevdate >= Date('0101' + Year(?))) j'ai utilisé (recevdate >= Date(Replace('01/01/1900','1900',year(?)-1))) et cela a fonctionné. Je suis toujours ouvert à une meilleure façon de le faire, mais je vais aller avec ça jusque-là.

0

Compte tenu des 01/01 et 12/31 codées en dur des valeurs dans le prédicat, pourquoi ne pas utiliser:

YEAR(recevdate) = YEAR(?) - 1 

serait-ce pas la façon la plus simple de l'écrire?

+0

Techniquement, Oui. Cependant, cela fonctionne si je voudrais sélectionner toutes les dates qui tombent dans un an. Et si je voulais choisir des dates trimestrielles? Pour cela, il serait plus facile de coder en dur la partie mois et jour du début et de la fin du trimestre et de paramétrer l'année. – Skadoosh

+0

Eh bien peut-être, mais ce n'est pas ce qui était dans la question initiale, et la règle de l'année moins 1 tombe dans cette situation. Dans tous les cas, MDY() doit être un bien meilleur ami que n'importe quelle méthode de manipulation de chaîne, sûrement: (recevdate> = MDY (?, 1,? - 1) AND recevdate RET