Cet article explore les méthodes pour résoudre ce problème, allant de la simple concaténation à la construction dynamique de clauses WHERE.
Le Problème : La "Soupe" de Guillemets
L'objectif est simple : créer une action CAS qui prend un nom d'utilisateur en paramètre et crée une table filtrée sur ce nom via fedSQL.execDirect.
Le défi réside dans la syntaxe. La définition de l'action est elle-même une chaîne de caractères (souvent entre guillemets doubles). La requête FedSQL est une chaîne à l'intérieur de cette définition (souvent entre guillemets simples). Enfin, la valeur littérale dans le SQL (le nom d'utilisateur) doit être entourée de guillemets simples.
Une tentative naïve échoue souvent car le paramètre n'est pas résolu correctement à l'intérieur de la chaîne littérale de la requête.
Solution 1 : La Concaténation Propre
La méthode la plus robuste pour insérer une variable CASL (le paramètre de votre action) dans la chaîne de requête FedSQL est d'utiliser l'opérateur de concaténation (||) à l'intérieur de la définition.
Il faut "sortir" de la chaîne SQL, concaténer la variable, puis "rentrer" dans la chaîne, tout en s'assurant que les guillemets simples nécessaires au SQL (') sont bien présents.
Exemple de code
Voici comment définir l'action pour qu'elle accepte un paramètre usernameQ et l'insère proprement :
proc cas;
builtins.defineActionSet /
name="tblMakers"
actions={
{
name="tableCreateParam"
/* Définition des paramètres attendus par l'action */
parms={{name="tblName" type="STRING" required=True}
{name="usernameQ" type="STRING" required=True}}
/* La définition utilise la concaténation pour insérer les variables */
definition=
"fedSQL.execDirect / query='create table casuser.'||strip(tblName)||' {options replace=true} as
select userName, TelNum
from CASUSER.have
where userName='''||strip(usernameQ)||''' ';"
}
};
run;
1
PROC CAS;
2
BUILTINS.defineActionSet /
3
name="tblMakers"
4
actions={
5
{
6
name="tableCreateParam"
7
/* Définition des paramètres attendus par l'action */
/* La définition utilise la concaténation pour insérer les variables */
12
definition=
13
"fedSQL.execDirect / query='create TABLE casuser.'||strip(tblName)||' {options replace=true} as
14
select userName, TelNum
15
from CASUSER.have
16
where userName='''||strip(usernameQ)||'''';"
17
}
18
};
19
RUN;
Notez la syntaxe du WHERE : '''||strip(usernameQ)||'''.
Le premier ' ferme la chaîne de la requête SQL.
Les deux ' suivants ('') sont une manière d'échapper un guillemet simple pour qu'il soit interprété comme un littéral par CASL, ce qui résultera en un guillemet ouvrant pour le SQL.
Ensuite vient la variable.
Et enfin la fermeture symétrique.
Solution 2 : Logique Dynamique et Clause WHERE Optionnelle
Une approche plus avancée consiste à utiliser la puissance du langage CASLà l'intérieur de la définition de l'action (definition=...). Puisque la définition contient du code CASL exécutable, vous pouvez utiliser des conditions IF/ELSE pour construire votre requête SQL dynamiquement avant de l'exécuter.
Cela permet, par exemple, de passer une clause WHERE complète ou de la laisser vide.
Exemple de code avancé
/* Astuce : gérer la longueur maximale des chaînes citées si nécessaire */
%let _sv_quotelenmax=%sysfunc(getoption(quotelenmax));
options noquotelenmax;
proc cas;
builtins.defineActionSet /
name="tblMakers"
type="CASL"
actions={
{
name="tableCreateParam"
parms={ {name="tblName" type="STRING" required=True}
{name="whereClause" type="STRING" required=False}
}
definition=
"
/* Logique CASL interne : vérifier si le paramètre existe */
if exists('whereClause') then whereClause=catx(' ','where',whereClause);
else whereClause='';
/* Construction et exécution de la requête */
fedSQL.execDirect / query='create table casuser.'||tblName||' {options replace=true} as
select userName, TelNum
from CASUSER.have '||whereClause||' ';
"
}
};
run;
options &_sv_quotelenmax;
1
/* Astuce : gérer la longueur maximale des chaînes citées si nécessaire */
/* Logique CASL interne : vérifier si le paramètre existe */
18
if exists('whereClause') then whereClause=catx('','where',whereClause);
19
else whereClause='';
20
21
/* Construction et exécution de la requête */
22
fedSQL.execDirect / query='create TABLE casuser.'||tblName||' {options replace=true} as
23
select userName, TelNum
24
from CASUSER.have '||whereClause||'';
25
"
26
}
27
};
28
RUN;
29
30
options &_sv_quotelenmax;
Note :
Utilisation
Cette méthode offre une flexibilité totale lors de l'appel de l'action :
proc cas;
/* Appel avec un filtre complexe */
tblMakers.tableCreateParam /
tblName="resultat1"
whereClause="userName='User 1' or TelNum = 333333";
/* Appel sans filtre (crée une copie complète) */
tblMakers.tableCreateParam /
tblName="resultat2";
run;
1
PROC CAS;
2
/* Appel avec un filtre complexe */
3
tblMakers.tableCreateParam /
4
tblName="resultat1"
5
whereClause="userName='User 1' or TelNum = 333333";
6
7
/* Appel sans filtre (crée une copie complète) */
8
tblMakers.tableCreateParam /
9
tblName="resultat2";
10
RUN;
L'intégration de FedSQL dans les actions définies par l'utilisateur ne nécessite pas de manipulations de chaînes illisibles. En utilisant l'opérateur de concaténation || et en tirant parti de la capacité du paramètre definition à exécuter de la logique CASL (comme if exists), vous pouvez créer des actions robustes, lisibles et hautement paramétrables.
Avertissement important
Les codes et exemples fournis sur WeAreCAS.eu sont à but pédagogique. Il est impératif de ne pas les copier-coller aveuglément sur vos environnements de production. La meilleure approche consiste à comprendre la logique avant de l'appliquer. Nous vous recommandons vivement de tester ces scripts dans un environnement de test (Sandbox/Dev). WeAreCAS décline toute responsabilité quant aux éventuels impacts ou pertes de données sur vos systèmes.
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.