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.
Wichtiger Haftungsausschluss
Die auf WeAreCAS.eu bereitgestellten Codes und Beispiele dienen Lehrzwecken. Es ist zwingend erforderlich, sie nicht blind in Ihre Produktionsumgebungen zu kopieren. Der beste Ansatz besteht darin, die Logik zu verstehen, bevor sie angewendet wird. Wir empfehlen dringend, diese Skripte in einer Testumgebung (Sandbox/Dev) zu testen. WeAreCAS übernimmt keine Verantwortung für mögliche Auswirkungen oder Datenverluste auf Ihren Systemen.
SAS und alle anderen Produkt- oder Dienstleistungsnamen von SAS Institute Inc. sind eingetragene Marken oder Marken von SAS Institute Inc. in den USA und anderen Ländern. ® zeigt die Registrierung in den USA an. WeAreCAS ist eine unabhängige Community-Site und nicht mit SAS Institute Inc. verbunden.
Diese Website verwendet technische und analytische Cookies, um Ihre Erfahrung zu verbessern.
Mehr erfahren.