Я использовал макросвалю SAS для хранения 2 запросов sql (для них два макроса) для динамического выполнения. Разница в том, что это строка запроса для SAS SQL, а другая - строка запроса для MS SQL, которая будет выполнена с помощью сквозного объекта. Эти два запроса составлены очень точно. Я использовал% STR и% NRSTR для формирования строк запроса и сделал их сохраненными в макропеременных. Ниже целая часть написанного макро функции:Ссылка на макро переменные для динамического SQL-запроса в SAS
%LET initialDate=19Oct2016;
%LET lastDate=19Oct2016;
%MACRO compressDataSetFirstTime(table, library=ANY);
PROC SQL NOPRINT;
/*Get the character variables*/
SELECT name, varnum INTO :characterVariableList SEPARATED BY ', '
FROM DICTIONARY.COLUMNS
WHERE libname="&library" AND memname="&table" AND type='char'
ORDER BY varnum;
/*Get the numeric variables*/
SELECT name, varnum, type INTO :numericVariableList SEPARATED BY ', '
FROM DICTIONARY.COLUMNS
WHERE libname="&library" AND memname="&table" AND type='num'
ORDER BY varnum;
%PUT 文字變數清單:&characterVariableList;
%LET characterVariableList=(&characterVariableList);
%LET numericVariableList=%STR(&numericVariableList,);
%PUT 數值變數清單:&numericVariableList;
%LET queryString=%STR(SELECT); %LET macroClause=%STR(INTO);
%LET queryMSSQL=%STR(SELECT)&numericVariableList;
%LET listNumber=%SYSFUNC(COMPRESS(%EVAL(%SYSFUNC(COUNT(&characterVariableList, %STR(,)))+1)));
%PUT 共有&listNumber.個文字型態變數。;
/*Compose the query for macro and the mssql query.*/
%DO variableNumber=1 %TO &listNumber;
%IF &variableNumber LT &listNumber %THEN %DO;
%LET variableName=MAX(LENGTH(STRIP(%SCAN(&characterVariableList, &variableNumber)))),;
%LET queryString=&queryString&variableName;
%LET macroClause=¯oClause%STR(:variable&variableNumber,);
%LET variableNameMSSQL=SUBSTRING(%SCAN(&characterVariableList, &variableNumber), 1, %NRSTR(%SYSFUNC%(COMPRESS%(&)variable&variableNumber))) AS %SCAN(&characterVariableList, &variableNumber),%STR();
%LET queryMSSQL=&queryMSSQL&variableNameMSSQL;
%END;
%ELSE %DO;
%LET variableName=MAX(LENGTH(STRIP(%SCAN(&characterVariableList, &variableNumber))));
%LET queryString=&queryString&variableName;
%LET macroClause=¯oClause%STR(:variable&variableNumber);
%LET variableNameMSSQL=SUBSTRING(%SCAN(&characterVariableList, &variableNumber), 1, %NRSTR(%SYSFUNC%(COMPRESS%(&)variable&variableNumber))) AS %SCAN(&characterVariableList, &variableNumber);
%LET queryMSSQL=&queryMSSQL&variableNameMSSQL;
%END;
%END;
%LET queryString = &queryString¯oClause%STR(FROM &library..&table WHERE dates BETWEEN "&initialDate"D AND "&lastDate"D;);
%LET queryMSSQL = &queryMSSQL%STR(FROM dbo.&table WHERE dates BETWEEN %NRSTR("%SYSFUNC(PUTN("&initialDate"D, YYMMDD10.))") AND %NRSTR("%SYSFUNC(PUTN("&lastDate"D, YYMMDD10.))"););
%PUT The query string with macro clause:&queryString;
/*Execute the query for macro*/
&queryString
/*
This is for examination.
%DO checkNumber=1 %TO &listNumber;
%PUT variable&checkNumber.接受到的長度:%SYSFUNC(TRIM(&&variable&checkNumber));
%END;*/
%PUT 遞過功能MSSQL查詢語句:&queryMSSQL;
/*Execute the mssql query with the pass-through facility*/
CONNECT TO SQLSVR AS sjconn
(DATABASE="***" USER=*** PASSWORD=***);
CREATE TABLE Desirable_Result AS
SELECT *
FROM connection to sjconn
(
/* The printed result of queryMSSQL from log using %PUT. */
/* &queryMSSQL */
);
DISCONNECT FROM sjconn;
QUIT;
%MEND;
проблема, которую я встретил это запрос сохраняется в макропеременной не может быть выполнен в PROC SQL с проходным объектом.
Второй запрос состоит из функции SUBSTRING в MSSQL,% SYSFUNC и некоторые макропеременные, которая появляется как следующий, с% PUT:
SELECT SUBSTRING(var, 1, %SYSFUNC(COMPRESS(&len_var))) AS var FROM table WHERE date BETWEEN "%SYSFUNC(PUTN("&firstdate"D, YYMMDD10.))" AND
"%SYSFUNC(PUTN("&lastdate"D, YYMMDD10.))";
Предположит & запроса хранит строку запроса, мои проблема в том, что если я использовал напечатанный результат в журнале и поместил его в PROC SQL с помощью сквозного средства, он работал, но если я использовал запрос & и поместил его в PROC SQL с помощью сквозного средства, он не удался.
В двух словах,
Это работает
CONNECT TO SQLSVR AS conn (related setting);
CREATE TABLE TMP AS
SELECT *
FROM connection to conn
(
/* The following query is the result I coped from the log where I used %PUT to print <br> the content of &query */
SELECT SUBSTRING(var, 1, %SYSFUNC(COMPRESS(&len_var))) AS var
FROM table
WHERE date BETWEEN "%SYSFUNC(PUTN("&firstdate"D, YYMMDD10.))" AND "%SYSFUNC(PUTN("&lastdate"D, YYMMDD10.))";
);
Это не удается
CONNECT TO SQLSVR AS conn (*related setting*);
CREATE TABLE TMP AS
SELECT *
FROM connection to conn
(
&query
);
Сообщение об ошибке в лог-дисплеях, что синтаксис около 'SYSFUNC' неверна.
Любая подсказка, почему это так?
Возможно, я совсем не здесь, но ваш SYSFUNC не имеет знака процента, как у вас в одном месте. Im ссылаясь на переменные даты в предложении where. похоже, что это должна быть функция put или аналогичная. это даже необходимо, так как вы создаете константы даты & firstdate и & lastdate. Но вы говорите, что это работает в случае 1. – Jonas
@ Джонас, это недостающая часть, потому что моя неосторожная публикация. Я проверил содержимое (моего вопроса) еще раз. Спасибо за ваше упоминание. –