SAS PassThru to Snowflake using EXECUTE( %include <program?) by SNOW; Error - sas

This process works with pass thru to Teradata. We are migrating to Snowflake. I create a program using a data step and put statements INSERT INTO TEMPTABLE VALUES('VAR', 'VAR', 'VAR, VAR', 'VAR, 'VAR', 'VAR'); The execute () by snow; works when I copy each record into the direct sas code. However, we don't know how many rows we will have on a given day and this process is automated, so the this was a way to be hand free.
The TD code that works great:
EXECUTE(
BT;
%include "/&srv./&fldr./programs/ORG_JOB_DPT_LKP.sas";
ET;
) BY TERA;
Previous errors are similar for the BT and ET:
ERROR: CLI execute error: SQL compilation error: syntax error line 1 at position 0 unexpected '%'.
I have also tried to send the multiple insert rows over as a macro variable with a %let = %();
I receive the same unexpected "&" when trying to call the variable.
I haven't been able to find any documentation that suggests this shouldn't work.

Related

OCI 19c - Parsing a PL/SQL statement that contains SELECT-FROM-INTO statements

I have a need to parse queries using OCI. For the most part - it is working. However I ran into a problem today that I am not able to figure out. For the time being - it looks like it's either a bug in OCI (currently using 19c 32bit) - or for some reason these kinds of statements are being ignored.
Whenever a SQL query contains SELECT-FROM-INTO statements - the entire query is ignored when OCIStmtExecute is invoked with OCI_PARSE_ONLY. It doesn't matter if there are invalid entity names / syntax in the query. I tried to find some additional info online regarding this particular situation - but I found nothing of use.
The query in question is below (the query is intentionally using garbage entity names to illustrate the strange behavior)
BEGIN
SELECT ColumnThatDoesntExist FROM DerpyTable INTO ThisVariableDoesntExist WHERE YeahRight = :BindName;
END
The statement preparation code / execution code is below
...
...
if (OCIStmtPrepare2(connectionHandle
, &statementHandle
, errorHandle
, command
, commandLength
, nullptr
, 0
, OCI_NTV_SYNTAX
, OCI_DEFAULT))
ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);
...
...
if (OCIStmtExecute(connectionHandle
, statementHandle
, errorHandle
, 0
, 0
, 0, 0, OCI_PARSE_ONLY))
ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);
In this particular test - OCIStmtExecute should be failing - however OCI_SUCCESS (aka 0) is returned when OCIStmtExecute is invoked. Are there additional flags I should be using for these kind of statements or should I be looking at another approach?
I tried prepending the query with EXPLAIN PLAN FOR and invoke OCIStmtExecute with the default flag - but that just results in a missing-keyword error.
It is not a bug in the OCI the return code OCI_SUCCESS (aka 0) is correct. It sent your statement to to the data base.
Your statement is an anonymous block, indicated by BEGIN, and contains errors. You can do what you want, but you have to define the variable you select into. You have not done that so that would be 1 error. Also the INTO clause comes before the FROM so the statement should be "select...INTO...from", that would be error 2. Finally if it is true the column you select actually does not that will also generate a "compile" time error, that would be error 3. Also I believe EXPLAIN PLAN for an anonymous block, is also invalid, but it been a long time since I ran into it.
But you can try the following:
declare
ThisVariableDoesntExist varchar2(50), -- or the correct data type
begin
select columnthatdoesntexist
into thisvariabledoesntexist
from derpytable
where yeahright = :bindname;
end;
Note: As an anonymous block the above should run (if the column actually exists). However, you will not get output. You may wish to add
dbms_output.put_line('Value=' || ThisVariableDoesntExist);
Oracle object names are not case sensitive and echoed back form Oracle will be folded to upper case, so it bast to avoid CamelCase and instead use snake_case.

Why is TIMEOUT= argument not recognized within SAS PROC HTTP?

I'm trying to account for missing files at a specific URL. For example, running PROC HTTP to get the following Excel file https://www2.census.gov/programs-surveys/cps/tables/time-series/historical-poverty-thresholds/thresh17.xls runs without timing out, eventually returning a 304 code. The SAS documentation clearly lists TIMEOUT= as an optional argument, but when I try to use it I get a syntax error:
ERROR 22-322: Syntax error, expecting one of the following: ;, AUTH_ANY, AUTH_BASIC, AUTH_NEGOTIATE, AUTH_NONE, AUTH_NTLM, CLEAR_CACHE, CLEAR_CONN_CACHE, CLEAR_COOKIES, CT, EXPECT_100_CONTINUE,
FOLLOWLOC, HEADERIN, HEADEROUT, HEADEROUT_OVERWRITE, HTTP_TOKENAUTH, IN, METHOD, NOFOLLOW, NOFOLLOWLOC, NO_CONN_CACHE, NO_COOKIES, OUT, PROXYHOST, PROXYPASSWORD, PROXYPORT,
PROXYUSERNAME, PROXY_AUTH_BASIC, PROXY_AUTH_NEGOTIATE, PROXY_AUTH_NONE, PROXY_AUTH_NTLM, URL, VERBOSE, WEBAUTHDOMAIN, WEBPASSWORD, WEBUSERNAME.
ERROR 202-322: The option or parameter is not recognized and will be ignored.
Here is my code:
filename resp "C:\response";
proc http
url="https://www2.census.gov/programs-surveys/cps/tables/time-series/historical-poverty-thresholds/thresh17.xls";
method="GET"
out=resp
TIMEOUT=5;
run;
Is there a different way to account for timeout issues within SAS?
Most likely you are not running SAS version 9.4M5.
The 9.4 What's new documentation states in 9.4M5 (September 2017)
PROC HTTP adds a DEBUG statement, the OAUTH_BEARER= procedure option and TIMEOUT= procedure option, and response status macro variables.

SAS data step error "too long for buffer"

I am just trying to load a SAS file someone else sent. I can open the dataset by just clicking on it and I can run proc contents. However, when I tried to copy the data to the work library, or run some summary statistics, this error message occurred:
ERROR: An internal error has occurred while reading a compressed file.
Please call your SAS Site Representative and report the
following: compress offset = 330 , de-compress offset = 320 , compress buf = "" .
ERROR: Record in file lib1.file_name.DATA is too
long for buffer.
I tried to increase the bufsize options bufsize=32768 or use
compress = Yes, but neither helped. Any suggestions?
It seems your dataset is damaged.
So you can try to repair with proc datasets and this statement : repair
Here an example :
PROC DATASETS LIB = WORK;
REPAIR JUNESALES;
QUIT;
source :
http://www2.sas.com/proceedings/forum2007/070-2007.pdf
Otherwise you have to get a new file of your dataset (if you have a backup it could be useful).
Regards,

Conditionally terminate SAS

I am trying to stop the processing of a SAS program if a certain condition has been met. I have a macro variable created and if that variable is > 0.5 then I want a hard stop of the program.
Current program looks like
data a1;
set Server.a2;
run;
%macro1(a1);
%macro2(_t1); /* _t1 generated from %macro1.
data _null_;
if %stopit(_t2) > 0.5 then `?????`; /* _t2 generated from %macro2.
run;
%macro3;
%macro4;
If %macro(_t2) > 0.5, I want to stop of whole program without running the rest (%macro3 and %macro4)
Use following statement:
abort abend;
Personally I tend to always use abort cancel; (or %abort cancel;) as it offers flexibility when running in interactive mode and in batch mode.
Interactively it will just cancel the submitted code (but leave your session open).
In batch mode it will stop the entire job.
There are additional options as well. You can find a full list in the documentation here.
There's also the endsas command but I don't like that as it closes the current interactive session (and it's more difficult to execute conditionally).
Here's an example:
%let x = 1;
data _null_;
if &x then abort cancel;
put "This won't print";
run;
%put This won't print either;
The results in the log will show:
ERROR: Execution terminated by an ABORT CANCEL statement at line 4 column 14.
_ERROR_=1 _N_=1

Strange error due to misuse of %sysrput in SAS

I am using AIX 6.1 with SAS 9.1.3
I have a program running in PC SAS 9.1
The program will rsubmit to unix.
Now, I convert the program to be totally running in AIX 6.1
The program fails very strangely.
After investigation, it is due to the %sysrput
Here is a simplified version of the program:
options mPrint mLogic symbolGen ;
%macro combine( startdate= , fullprefix= );
data _null_ ;
call symput( 'plength',compress(length(compress("&fullprefix."))));
run;
data _null_ ;
length balance 8. ;
balance= 1 + &plength.;
run;
%mEnd;
data _null_ ;
call symput( 'refdate', put(today(),date9.));
run;
%put &refdate.;
* -- If I forget to comment out the sysrput, the plength cannot be resolved -- ;
%sysrput refdate=&refdate.;
%put &refdate.;
%combine( startdate= "&refdate."d, fullprefix=a_filename_prefix );
(Sorry that the wordings are not meaningful, I just want to do a demo.)
Actually, in AIX, I should not use %sysrput
I just forget to comment it out.
But, if I forget this, there would be error in the plength macro variable in the balance= statement. This is very strange.
To solve, simply comment out the %sysrput is ok.
But, does anyone know why the %sysrput will cause failure in a macro variable in the macro ?
Alvin SIU
It's hard to tell from your simplified version of your question, but if you are asking why the macro variable plength is not present after your macro executes, it is because you must define it as global in your macro code itself. In other words:
%macro combine( startdate= , fullprefix= );
%global plength;
...
%mend;
And yes, if you use the %SYSRPUT command from a SAS session not under control of SAS/CONNECT, you will get a SAS ERROR; and getting a SAS error will put your non-interactive session into "syntax-check" mode, in which case the remaining statements in your program will not execute completely.
This last bit is a common misunderstanding when converting code from a SAS/CONNECT environment to "plain old SAS". When you use SAS/CONNECT, the "server" side of the connection is started with the "-NOSYNTAXCHECK" option.
After investigation with some little testing. maybe this is the answer.
Actually, I will use OPTIONS ERRORABEND in all batch SAS program to stop the SAS in case of error. This works for many errors and functions just perfectly.
The %SYSRPUT statement do give out error message saying ... options DMR ...
But the program does not abend stop here.
It does not give any message saying ... OBS=0 ...
It just go on.
So, I just 'think' that this is some minor error just like LIBNAME a non-exist directory and SAS will continue 'normally'.
(BTW, I think that the SYSRPUT error has turn on SYNTAX CHECK mode silently, without any notification nor hint.)
The next %PUT statement is normal, same value as previous one.
This mislead me that the program is running normally.
The next statements are also normal. There are many SYMBOLGEN, MPRINT and MLOGIC messages.
So, this further mislead me that the program is running very very normally.
After the call symput plength statement, there is a NOTE: Numeric values have been converted ...
This further mislead me the program is running normally.
Until now (after so many look-like normal messages), there is a NOTE saying SAS set option OBS=0 ...
(Maybe this NOTE will appear only after the RUN statement.)
This OBS=0 message is actually the hints which tell SAS is using SYNTAX CHECK mode.
Maybe this OBS=0 is caused by the SYSRPUT error. But, because there are so many look-like normal messages after the SYSRPUT error, I just overlook this OBS=0 message.
Actually, the call symput is so simply and should not cause any error.
This just further complicate the situation.
As SAS is in SYNTAX CHECK mode, this is why causing the look-like error in the plength variable in the balance statement.
This is the whole story.
Anyway, in order to prevent to enter into this complicated and misleading situation, just remember to comment out all the %SYSRPUT will do.