string input;
DateTime db;
Console.WriteLine("Enter Date in this Format(YYYY-MM-DD): ");
input = Console.ReadLine();
db = Convert.ToDateTime(input);
//////// this methods convert string value to datetime
///////// in order to print date
Console.WriteLine("{0}-{1}-{2}",db.Year,db.Month,db.Day);
Как писал Ричард, макросы в стиле функции испускают код SAS. Общее правило разработки макросов в стиле функции заключается в том, что они содержат только макроязычные выражения. Любой код SAS, который они содержат, будет испускаться. Исторически сложилось так, что это затруднило / раздражало написать макрос функционального стиля, который обрабатывал бы данные, подобные тому, который вы делали бы с помощью шага DATA. К счастью, SAS добавила функцию DOSUBL, которая упрощает запись макросов в стиле функции, которые выполняют код SAS в «боковом сеансе» и испускают результат. См. Статью Рика Лэнгстона .
Вот пример макрофайла в стиле функции, который использовал DOSUBL для подсчета количества записей в таблице и испускает счет. (Это очень неэффективный способ получить показатель записи, просто пример выполнения чего-то в SQL).
%macro SQLcount(table);
%local rc emit;
%let rc=%sysfunc(dosubl(%nrstr(
proc sql noprint;
select count(*) into :emit trimmed
from &table
quit;
)));
&emit
%mend ;
Его можно использовать как:
proc sql ;
select name
,%SQLcount(sashelp.shoes) as ShoeCount /*emits 395*/
from sashelp.class
;
quit ;
Когда вышеперечисленный шаг запускается, он вернет 19 строк имен из sashelp.class, а значение ShoeCount будет 395 в каждой строке. Обратите внимание, что макрос SQLcount выполняется только один раз. В то время как этап PROC SQL компилируется / интерпретируется, вызов SQLcount просматривается и выполняется макрос и испускает 395. Шаг становится:
proc sql ;
select name
,395 as ShoeCount /*emits 395*/
from sashelp.class
;
quit ;
DOSUBL использует «боковой сеанс» для выполнения кода, который позволяет выполнить шаг PROC SQL в боковом сеансе, в то время как основной сеанс интерпретирует шаг PROC SQL.
Я не могу сказать из вашего вопроса, подходит ли этот вариант использования. Возможно, вам нужен макрос функционального стиля, в котором вы могли бы передавать ему значения из таблицы, и макрос выполнялся по каждому значению и возвращал что-то. Предположим, что у вас была таблица, которая была списком имен таблиц, и хотела использовать SQL для подсчета записей в каждой таблице:
data mytables ;
input table $20. ;
cards ;
sashelp.shoes
sashelp.class
sashelp.prdsale
;
quit ;
Вы можете сделать это, используя функцию resolve (), чтобы вызывать макросы на основе данных, задерживая выполнение макроса до выполнения оператора SELECT:
proc sql ;
select table
,resolve('%SQLcount('||table||')') as count
from mytables
;
quit ;
При этом SQLcount будет вызываться три раза и будет возвращать количество записей в каждом наборе данных.
table count
---------------------------
sashelp.shoes 395
sashelp.class 19
sashelp.prdsale 1440
Вызов макроса не отображается, когда интерпретируется шаг PROC SQL, поскольку он скрыт одиночными кавычками. Затем функция разрешения вызывает макрос, когда выполняется оператор SELECT, передавая значение table
в качестве значения параметра, а макрос испускает счетчик записей. Это похоже на подход CALL EXECUTE для использования данных для вызова макросов.
Макрофункции не возвращают значения. Макрофункция может «испускать» исходный код, который
Для вашего случая, когда вы хотите «делать» вещи в SQL, вы можете записывать представления SQL, которые затем
%sysfunc(open())
и %sysfunc(set())
и %sysfunc(getvarn())
и %sysfunc(getvarc())
. Не все функциональные возможности SQL могут использоваться этой методикой - select something into :result
, это должно быть представление с select something
, а макрос будет getvarc
читать результат.
Доступ, выполняемый в режиме open / set / get, не приводит к возникновению границы шага, поэтому макропроцессор может продолжить свою логику и в конечном итоге испустить исходный код для потребления уровня фрагмента. (Потребитель - это исполнитель SAS, который обрабатывает макрокод и неявно компилирует и запускает шаги SAS)
Похоже, вы можете создать функцию FCMP с помощью proc fcmp
. Это в основном способ создания собственных SAS-функций, которые можно использовать в шагах proc sql
и data
. Например:
/******************************************************************************
** PROGRAM: COMMON.FCMP_DIV.SAS
**
** DESCRIPTION: PERFORMS A MATHEMATICAL DIVISION BUT WILL RETURN NULL IF THE
** NUMERATOR OR DENOMINATOR IS MISSING (OR IF THE DIVISOR IS 0).
**
******************************************************************************/
proc fcmp outlib=common.funcs.funcs;
function div(numerator, denominator);
if numerator eq . or denominator in (0,.) then do;
return(.);
end;
else do;
return(numerator / denominator);
end;
endsub;
run;
Пример использования (пример - шаг данных, но одинаково хорошо работает в SQL):
data x;
x1 = div(1,0);
x2 = div(1,.);
x3 = div(1,1);
x4 = div(0,0);
x5 = div(0,.);
x6 = div(0,1);
x7 = div(.,0);
x8 = div(.,.);
x9 = div(.,1);
put _all_;
run;
Вы заявляете, что хотите:
запускать довольно сложную логику при каждом наблюдении набора данных
blockquote>. Для этого вы должны использовать язык SAS вместо макропроцессора или PROC SQL. Вы можете использовать шаг данных. Или для еще более сложной логики вы должны посмотреть PROC DS2.
resolve(cats('%SQLcount(',table,')')) as count
– Quentin 17 July 2018 в 16:17