Dieser Artikel untersucht Methoden zur Lösung dieses Problems, von der einfachen Verkettung bis zur dynamischen Konstruktion von WHERE-Klauseln.
Das Problem: Der "Anführungszeichen-Salat"
Das Ziel ist einfach: eine CAS-Aktion zu erstellen, die einen Benutzernamen als Parameter annimmt und eine Tabelle filtert, die auf diesem Namen basiert, über fedSQL.execDirect.
Die Herausforderung liegt in der Syntax. Die Aktionsdefinition selbst ist eine Zeichenkette (oft in doppelten Anführungszeichen). Die FedSQL-Abfrage ist eine Zeichenkette innerhalb dieser Definition (oft in einfachen Anführungszeichen). Schließlich muss der Literalwert in SQL (der Benutzername) in einfachen Anführungszeichen stehen.
Ein naiver Versuch schlägt oft fehl, da der Parameter innerhalb der literalisierten Abfragezeichenkette nicht korrekt aufgelöst wird.
Lösung 1: Die saubere Verkettung
Die robusteste Methode, um eine CASL-Variable (den Parameter Ihrer Aktion) in die FedSQL-Abfragezeichenkette einzufügen, ist die Verwendung des Verkettungsoperators (||) innerhalb der Definition.
Man muss die SQL-Zeichenkette verlassen, die Variable verketten und dann wieder in die Zeichenkette eintreten, wobei sichergestellt werden muss, dass die für SQL erforderlichen einfachen Anführungszeichen (') vorhanden sind.
Codebeispiel
So definieren Sie die Aktion, damit sie einen Parameter usernameQ akzeptiert und ihn korrekt einfügt:
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;
Beachten Sie die WHERE-Syntax: '''||strip(usernameQ)||'''.
Das erste ' schließt die SQL-Abfragezeichenkette.
Die nächsten beiden '' sind eine Möglichkeit, ein einfaches Anführungszeichen zu maskieren, damit es von CASL als Literal interpretiert wird, was zu einem öffnenden Anführungszeichen für SQL führt.
Dann kommt die Variable.
Und schließlich die symmetrische Schließung.
Lösung 2: Dynamische Logik und optionale WHERE-Klausel
Ein fortgeschrittenerer Ansatz besteht darin, die Leistungsfähigkeit der CASL-Sprache innerhalb der Aktionsdefinition (definition=...) zu nutzen. Da die Definition ausführbaren CASL-Code enthält, können Sie IF/ELSE-Bedingungen verwenden, um Ihre SQL-Abfrage vor der Ausführung dynamisch zu erstellen.
Dies ermöglicht es beispielsweise, eine vollständige WHERE-Klausel zu übergeben oder sie leer zu lassen.
Beispiel für erweiterten Code
/* 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 :
Verwendung
Diese Methode bietet bei Aufruf der Aktion volle Flexibilität:
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;
Die Integration von FedSQL in benutzerdefinierte Aktionen erfordert keine unleserlichen Zeichenkettenmanipulationen. Durch die Verwendung des Verkettungsoperators || und die Nutzung der Fähigkeit des definition-Parameters, CASL-Logik (wie if exists) auszuführen, können Sie robuste, lesbare und hochgradig parametrierbare Aktionen erstellen.
Important Disclaimer
The codes and examples provided on WeAreCAS.eu are for educational purposes. It is imperative not to blindly copy-paste them into your production environments. The best approach is to understand the logic before applying it. We strongly recommend testing these scripts in a test environment (Sandbox/Dev). WeAreCAS accepts no responsibility for any impact or data loss on your systems.
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. WeAreCAS is an independent community site and is not affiliated with SAS Institute Inc.
This site uses technical and analytical cookies to improve your experience.
Read more.