Passing Dynamic Parameters to FedSQL in a Custom Action
Simon 43 vistas
Nivel de dificultad
Débutant
Publicado el :
Consejo del experto
Simon
Successfully embedding FedSQL within a Custom Action hinges on resolving the nested quote syntax ("Quote Soup"). To secure your dynamic parameters, move away from static strings and embrace CASL logic construction: leverage the concatenation operator (||) and rigorous escaping ('') to assemble your SQL queries programmatically before execution.
This article explores methods to solve this problem, ranging from simple concatenation to the dynamic construction of WHERE clauses.
The Problem: The "Quote Soup"
The objective is simple: create a CAS action that takes a username as a parameter and creates a table filtered on that name via fedSQL.execDirect.
The challenge lies in the syntax. The action definition itself is a character string (often in double quotes). The FedSQL query is a string within that definition (often in single quotes). Finally, the literal value in the SQL (the username) must be enclosed in single quotes.
A naive attempt often fails because the parameter is not resolved correctly within the literal string of the query.
Solution 1: Clean Concatenation
The most robust method for inserting a CASL variable (your action's parameter) into the FedSQL query string is to use the concatenation operator (||) inside the definition.
You need to "exit" the SQL string, concatenate the variable, then "re-enter" the string, all while ensuring that the single quotes required for SQL (') are present.
Code Example
Here's how to define the action so that it accepts a usernameQ parameter and inserts it cleanly:
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;
Note the WHERE syntax: '''||strip(usernameQ)||'''.
The first ' closes the SQL query string.
The next two '' are a way to escape a single quote so that it is interpreted as a literal by CASL, which will result in an opening quote for SQL.
Then comes the variable.
And finally the symmetrical closing.
Solution 2: Dynamic Logic and Optional WHERE Clause
A more advanced approach is to use the power of the CASL language inside the action definition (definition=...). Since the definition contains executable CASL code, you can use IF/ELSE conditions to build your SQL query dynamically before executing it.
This allows, for example, to pass a complete WHERE clause or to leave it empty.
Advanced Code Example
/* 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 : Usage
This method offers complete flexibility when calling the 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;
Integrating FedSQL into user-defined actions does not require unreadable string manipulations. By using the concatenation operator || and leveraging the definition parameter's ability to execute CASL logic (like if exists), you can create robust, readable, and highly parametrizable actions.
Aviso importante
Los códigos y ejemplos proporcionados en WeAreCAS.eu son con fines educativos. Es imperativo no copiarlos y pegarlos ciegamente en sus entornos de producción. El mejor enfoque es comprender la lógica antes de aplicarla. Recomendamos encarecidamente probar estos scripts en un entorno de prueba (Sandbox/Dev). WeAreCAS no acepta ninguna responsabilidad por cualquier impacto o pérdida de datos en sus sistemas.
SAS y todos los demás nombres de productos o servicios de SAS Institute Inc. son marcas registradas o marcas comerciales de SAS Institute Inc. en los EE. UU. y otros países. ® indica registro en los EE. UU. WeAreCAS es un sitio comunitario independiente y no está afiliado a SAS Institute Inc.
Este sitio utiliza cookies técnicas y analíticas para mejorar su experiencia.
Saber más.