Fedsql

Gérer les comparaisons de dates en FedSQL

Simon 15 vues

L'arrivée de SAS© Viya et du moteur CAS (Cloud Analytic Services) a introduit l'utilisation de FedSQL, une implémentation normalisée du langage SQL conçue pour l'évolutivité. Cependant, FedSQL est beaucoup plus strict que le PROC SQL classique de SAS© Base, notamment en ce qui concerne les types de données.

Une erreur fréquente survient lors du filtrage de dates via des variables macro numériques.

Le Problème : Typage Fort vs Typage Faible

Dans SAS© classique (Base SAS©), une date n'est rien d'autre qu'un nombre (le nombre de jours depuis le 1er janvier 1960). Vous pouvez donc écrire sans problème : WHERE ma_colonne_date > 23040.

En FedSQL, les types sont stricts. Une colonne définie comme DATE ne peut pas être comparée directement à un INTEGER (entier). Si vous tentez d'injecter une macro-variable numérique brute dans votre requête CAS, vous obtiendrez l'erreur suivante :

ERROR: Operator is not unique: DATE > INTEGER

Cela signifie que le moteur ne sait pas comment comparer ces deux types de données incompatibles sans conversion explicite.

La Solution : Le Format ANSI

FedSQL respecte la norme ANSI SQL. Pour filtrer sur une date, vous devez fournir une valeur littérale sous la forme spécifique : DATE 'YYYY-MM-DD'

Le défi technique est de transformer votre macro-variable numérique (ex: 23040) en une chaîne de caractères formatée (ex: '2023-01-30'), tout en gérant les contraintes du macro-langage SAS© (cotes, tirets).

La Recette Technique

Pour construire cette chaîne dynamiquement, nous devons combiner trois outils :

  1. PUTN : Pour convertir le nombre brut en format date avec tirets (yymmddd10.).

  2. %QSYSFUNC : Pour exécuter PUTN tout en masquant les tirets (-). Sans le Q (Quoting), SAS© pourrait interpréter les tirets de la date (2023**-01-**30) comme des signes "moins" (soustraction).

  3. %TSLIT : Une macro fournie par SAS© qui résout le problème des cotes. En SQL, les littéraux doivent être entre simples cotes ('valeur'), mais les macros SAS© ne se résolvent pas à l'intérieur de simples cotes. %TSLIT (Time Share Literal) génère une chaîne entre simples cotes tout en permettant la résolution de la macro à l'intérieur.

Le Code Corrigé

Voici comment assembler ces éléments pour une requête FedSQL robuste :

1/* Exemple : Macro variable contenant une date numérique SAS */
2%let Aujourdhui = 23040;
3 
4PROC FEDSQL;
5 select * from ma_librairie.ma_table_cas
6 /* La syntaxe magique : DATE suivi de la chaîne formatée */
7 where dateColumn >= date %tslit(%qsysfunc(putn(&Aujourdhui, yymmddd10.)));
8QUIT;
Regardons ce qui se passe lors de la compilation de la ligne WHERE :

putn(&Aujourdhui, yymmddd10.) transforme 23040 en 2023-01-30.

%qsysfunc protège la chaîne 2023-01-30 pour qu'elle soit traitée comme du texte pur.

%tslit enveloppe le tout pour produire '2023-01-30'.

Le code final envoyé au serveur CAS est : where dateColumn >= date '2023-01-30'

Lorsque vous travaillez avec FedSQL dans CAS :

  • Oubliez la comparaison directe Date vs Nombre.

  • Utilisez toujours le littéral ANSI DATE 'YYYY-MM-DD'.

  • Utilisez le combo %TSLIT + %QSYSFUNC pour injecter vos variables macro proprement.