#json #sas #sas-ds2
#json #sas #sas-ds2
Вопрос:
Я пытаюсь проанализировать файл JSON, используя пакет JSON, предусмотренный proc ds2
в SAS9.3 Maintenance 3, согласно сообщению в блоге Криса Хемедингера здесь:
http://blogs.sas.com/content/sasdummy/2015/09/28/parse-json-from-sas/
Казалось, все работало нормально, пока я не перезапустил сеанс SAS, и теперь я продолжаю получать сообщение:
ERROR: Compilation error.
ERROR: Line 883: Ambiguous method call for method createparser. Multiple method declarations
match the given argument list.
Строка 883 (в данном случае) ссылается на строку, содержащую createParser
вызов. Вот несколько упрощенных кодов, которые могут воспроизвести ошибку:
data have;
set sashelp.class;
run;
proc ds2;
data want;
dcl package json j();
dcl int rc;
method run();
set have;
rc = j.createParser( name );
end;
enddata;
run;
quit;
Что я делаю не так?
Комментарии:
1. Просто повторите точный пример из сообщения в блоге, и он работает нормально. Так что это определенно что-то в моем коде.
2. Также пытался явно объявить переменную name и присвоить ей тип данных DS2, но это, похоже, тоже не помогло.
Ответ №1:
Я думаю, вы правы, что это ошибка со стороны SAS, и, к сожалению, я не вижу способа подтвердить SAS, что вы используете метод 3, а не метод 4. name
По какой-то причине простого объявления как символа недостаточно. Я бы посоветовал создать заявку с помощью SAS для этого.
Однако я думаю, что метод 1 здесь лучше, чем метод 2, учитывая, что вы на самом деле не хотите указывать размер чаевых. Просто переместите это в INIT (где оно все равно принадлежит) и используйте setparserinput
, как предлагается в документации:
data have;
set sashelp.class;
run;
proc ds2;
data want;
dcl package json j();
dcl double rc;
method init();
rc = j.createParser();
j.setParserInput(name);
end;
method run();
set have;
end;
enddata;
run;
quit;
Кроме того, похоже, что причиной, по которой работает пример, является character set
аргумент. UTF-8
или Unicode
будет работать (последнее на самом деле не будет работать по другим причинам, но не сломается по этой причине), в то время WLatin1
как , ANSI
, или ASCII
не будет. По-видимому, установка его в качестве символа UTF-8 заставляет SAS понимать, что это действительно символ?
data have;
set sashelp.class;
run;
proc ds2;
data want(overwrite=yes);
dcl package json j();
dcl char(50) character set utf8 name;
dcl double rc;
method init();
rc = j.createParser( name );
end;
method run();
set have;
end;
enddata;
run;
quit;
Ответ №2:
Согласно документации (https://support.sas.com/documentation/cdl/en/ds2ref/68052/HTML/default/viewer.htm#n1w9ms65zrao57n1p1yt4029jcwt.htm ) они используют перегрузку метода в createParser. Есть 4 метода на выбор, и кажется, что каким-то образом SAS не может определить, какой из 4 я пытаюсь вызвать:
Форма 1:
package.CREATEPARSER ( );
Форма 2:
package.CREATEPARSER (json-text, tipping-size);
Форма 3:
package.CREATEPARSER (json-text);
Форма 4:
package.CREATEPARSER (tipping-size);
Я нашел уродливое решение, которое заключается в простом вызове формы 2, чтобы сделать вызов однозначным. Я установил переломный момент на 32767, поскольку я работаю с данными в таблицах SAS, и ни один из результатов в любом случае не будет длиннее этого. Окончательный код:
proc ds2;
data want (overwrite=yes);
dcl package json j();
dcl int rc;
method init();
set have;
rc = j.createParser( name , 32767 );
end;
enddata;
%runquit;