Este artículo explora los métodos para resolver este problema, desde la simple concatenación hasta la construcción dinámica de cláusulas WHERE.
El Problema: La "Sopa" de Comillas
El objetivo es simple: crear una acción CAS que tome un nombre de usuario como parámetro y cree una tabla filtrada por ese nombre a través de fedSQL.execDirect.
El desafío reside en la sintaxis. La definición de la acción es en sí misma una cadena de caracteres (a menudo entre comillas dobles). La consulta FedSQL es una cadena dentro de esta definición (a menudo entre comillas simples). Finalmente, el valor literal en SQL (el nombre de usuario) debe ir entre comillas simples.
Un intento ingenuo a menudo falla porque el parámetro no se resuelve correctamente dentro de la cadena literal de la consulta.
Solución 1: La Concatenación Limpia
El método más robusto para insertar una variable CASL (el parámetro de su acción) en la cadena de consulta FedSQL es usar el operador de concatenación (||) dentro de la definición.
Hay que "salir" de la cadena SQL, concatenar la variable y luego "volver a entrar" en la cadena, asegurándose de que las comillas simples necesarias para SQL (') estén presentes.
Ejemplo de código
Aquí se explica cómo definir la acción para que acepte un parámetro usernameQ y lo inserte correctamente:
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;
Tenga en cuenta la sintaxis de WHERE: '''||strip(usernameQ)||'''.
El primer ' cierra la cadena de la consulta SQL.
Los dos ' siguientes ('') son una forma de escapar una comilla simple para que CASL la interprete como un literal, lo que resultará en una comilla de apertura para SQL.
Luego viene la variable.
Y finalmente el cierre simétrico.
Solución 2: Lógica Dinámica y Cláusula WHERE Opcional
Un enfoque más avanzado consiste en usar la potencia del lenguaje CASLdentro de la definición de la acción (definition=...). Dado que la definición contiene código CASL ejecutable, puede usar condiciones IF/ELSE para construir su consulta SQL dinámicamente antes de ejecutarla.
Esto permite, por ejemplo, pasar una cláusula WHERE completa o dejarla vacía.
Ejemplo de código avanzado
/* 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 :
Uso
Este método ofrece total flexibilidad al llamar a la acción:
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;
La integración de FedSQL en las acciones definidas por el usuario no requiere manipulaciones de cadenas ilegibles. Al usar el operador de concatenación || y aprovechar la capacidad del parámetro definition para ejecutar lógica CASL (como if exists), puede crear acciones robustas, legibles y altamente parametrizables.
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.