मुझे एक लंबी एसक्यूएल स्क्रिप्ट पेस्ट करने में सक्षम होना चाहिए जिसमें एगिनिटी वर्कबेंच और एसएएस के बीच चर शामिल हैं। इसे आसान बनाने के लिए, मैं SQL क्वेरी को मैक्रो वेरिएबल में इस तरह से स्टोर कर रहा हूं: (नेटेज़ा स्टाइल वेरिएबल्स पर ध्यान दें)

%let myQuery = %str(
                      DROP TABLE this;
                      SELECT *
                      INTO SomeTable
                      FROM OtherTable
                      WHERE field = ${myVariable};
                      UPDATE TABLE foo
                      SET x = 1
                      WHERE
                          field = ${anotherVariable};
                    );

जब मेरा SAS प्रोग्राम चलता है, तो मुझे ${netezzaVariables} को अन्य मैक्रो वेरिएबल के टेक्स्ट से बदलने की आवश्यकता होती है जो पहले प्रक्रिया प्रवाह में निर्धारित होते हैं। अब तक, मैं इस मैक्रो वेरिएबल के भीतर टेक्स्ट को सफलतापूर्वक प्रतिस्थापित करने में सक्षम नहीं हूं और मुझे संदेह है कि अर्धविराम समस्याएं पैदा कर रहे हैं।

यहाँ मैं नीचे क्या करने का प्रयास कर रहा हूँ:

%let formattedText = %sysfunc(tranwrd(&myQuery,'${myVariable}','replacementText'));

इसके लिए लॉग दिखाता है:

NOTE: Line generated by the macro function "SYSFUNC".
DROP TABLE this;
! SELECT <the rest of the query is printed to console here>

मैंने ऊपर के बाकी लॉग को लिखना जारी नहीं रखा, क्योंकि त्रुटि SELECT शब्द पर है, जिसके नीचे एक लाल रेखा है। इस लाल रेखा के ठीक नीचे पाठ है:

त्रुटि 180-322: कथन मान्य नहीं है या इसका उपयोग उचित क्रम में किया गया है।

वास्तव में, यदि मैं लॉग के माध्यम से स्क्रॉल करता रहता हूं, तो क्वेरी में अर्धविराम के बाद वर्णों के प्रत्येक पहले सेट को उसी सटीक त्रुटि कोड के साथ रेखांकित किया जाता है। यह मुझे विश्वास दिलाता है कि एसएएस ने उस चयन से पहले अर्धविराम उठाया, इसका इस्तेमाल मैं जो कर रहा था उसे समाप्त करने के लिए किया, और अब सोचता है कि इस अर्धविराम के बाद का पाठ खुले कोड में है।

अंत में, मुझे यह जानने की जरूरत है कि मैक्रो वेरिएबल के भीतर सबस्ट्रिंग्स को कैसे बदला जाए, जिसका मान अर्धविराम युक्त एक बड़ी स्ट्रिंग है।

अग्रिम में धन्यवाद!

0
Joshua Schlichting 2 नवम्बर 2017, 06:18

3 जवाब

सबसे बढ़िया उत्तर

%sysfunc() के साथ स्ट्रिंग फ़ंक्शंस का उपयोग करते समय आपको उद्धरण चिह्नों का उपयोग करने की आवश्यकता नहीं है। इस मामले में %qsysfunc वह है जिसे आप ढूंढ रहे हैं, मुझे लगता है:

%let myQuery = %str(
                      DROP TABLE this;
                      SELECT *
                      INTO SomeTable
                      FROM OtherTable
                      WHERE field = ${myVariable};
                      UPDATE TABLE foo
                      SET x = 1
                      WHERE
                          field = ${anotherVariable};
                    );
%put &myQuery;

%let formattedText = %qsysfunc(tranwrd(&myQuery,${myVariable},replacementText));
%put &formattedText;
0
user667489 2 नवम्बर 2017, 13:29

समाधानों का सबसे सुरुचिपूर्ण नहीं है लेकिन यह काम करता है:

%let myQuery = %str(
                      DROP TABLE this;
                      SELECT *
                      INTO SomeTable
                      FROM OtherTable
                      WHERE field = ${myVariable};
                      UPDATE TABLE foo
                      SET x = 1
                      WHERE
                          field = ${anotherVariable};
                    );
data _null_;
call symput('formattedtext',tranwrd("%quote(%superq(myquery))","${myVariable}","replacementText"));
run;

%put %superq(formattedText);

केवल मैक्रो फ़ंक्शंस का उपयोग करके इसे करने का शायद एक तरीका है लेकिन मैं इसे काम पर नहीं ला सका।

आपके विशेष उदाहरण के लिए, call symput को सरल बनाया जा सकता था

call symput('formattedtext',tranwrd("&myquery","${myVariable}","replacementText"));

लेकिन यह विफल हो जाएगा यदि आपकी क्वेरी में दोहरे उद्धरण हैं जबकि जिस तरह से मैंने इसे ऊपर लिखा है वह इसका समर्थन करता है।

0
user2877959 2 नवम्बर 2017, 11:38

यहोशू:

एक सामान्य प्रयोजन समाधानकर्ता उपयोगी है यदि आपकी 'टेम्पलेट' अभिव्यक्ति में कई पैरामीटर हैं। नोट: एक टेम्प्लेट एक पैरामीटरयुक्त क्वेरी से अलग है, और संभावित रूप से अधिक खतरनाक है।

रिज़ॉल्वर के बिना आपको प्रत्येक पैरामीटर के लिए एक TRANWRD कोड करना होगा।

इस मैक्रो पर विचार करें जो मानता है कि टेम्पलेट में पैरामीटर हैं जो ${macro-var} द्वारा निर्दिष्ट हैं और पैरामीटर्स को मैक्रो-var मान से बदल दिया गया है। यह भी मान लें कि ऐसे कोई पैरामीटर नहीं हैं जो अंडरस्कोर (_) से शुरू होते हैं जो मैक्रोज़ के आंतरिक चर से टकरा सकते हैं।

%macro resolver(_template);
  %local _result;
  %local _tokenRx;
  %local _start _stop _position _length _token _macrovar _guard;

  %let _tokenRx = %sysfunc(prxparse(m/\${([^}]+)}/));
/*%put &=_tokenRx;*/

  %let _guard = 0;
  %let _start = 1;
  %let _stop = %length(&_template);
  %let _position = 0;
  %let _length = 0;

  %let _result = &_template;

  %syscall prxnext(_tokenRx, _start, _stop, _template, _position, _length);

  %do %while (&_position > 0);
/*  %put &=_start &=_stop &=_position &=_length; */
    %let _token = %qsubstr(&_template,&_position,&_length);
    %let _macrovar = %substr(&_token,3,%eval(%length(&_token)-3));

/*
    %put &=_token;
    %put &=_macrovar;
*/
    %if %symexist(&_macrovar) %then %do;
      %let _result = %qsysfunc(tranwrd(&_result,&_token,&&&_macrovar));
    %end;

    %syscall prxnext(_tokenRx, _start, _stop, _template, _position, _length);

    %let _guard = %eval (&_guard+1);
    %if &_guard > 1000 %then %let _position = 0;
  %end;

  %syscall prxfree(_tokenRx);

  %superq(_result)
%mend;

यहां आपकी टेम्प्लेटेड SQL क्वेरी (Proc SQL में समायोजित) पर लागू किया गया रिज़ॉल्वर है।

%let myQuery = %str(

    DROP TABLE this
;
    INSERT INTO SomeTable /* sas insert syntax */
    SELECT * FROM OtherTable
    WHERE ${field} = ${target}
;
    UPDATE foo
    SET x = 1
    WHERE
        field = ${anotherVariable}
;
);


%let field = name;
%let target = 'Jane';
%let myVariable = XYZ;
%let anotherVariable = 'John';

%put %resolver (%superq(myQuery));

proc sql;
  create table this (id int);
  create table SomeTable like sashelp.class;
  create table OtherTable as select * from sashelp.class;
  create table foo as select name as field, 0 as x from sashelp.class;

  %unquote(%resolver(%superq(myQUery)))
quit;
0
Richard 2 नवम्बर 2017, 11:55