suppress log10 errors for missing values in SAS - error-handling

I have the following bit of code that was provided by someone to establish if a mobile number begins with a 7:
if int(abs(mobile_telephone1)/10**int(log10(abs(mobile_telephone1)))) ne 7
then do .....
This works perfectly but if the value is missing I get large error messages and I was wondering if there is a way to suppress the error messages for this particular statement?

You can't suppress errors for a specific function (usually), but you could disable them before your datastep, then re-apply them after
options errors=0 ;
data xyz ;
/* some code */
run ;
options errors=25 ;
But why not just do it far more simply without running the risk of any errors...
data xyz ;
tel = 7123455678 ;
chartel = put(tel,12.) ;
if chartel =: '7' then istel = 1 ;
run ;

To more specifically answer your question (although Chris' solution is definitely the way to go), you can use the coalesce function.
if log10(coalesce(mobile_telephone1,1)) ...
Coalesce returns the first nonmissing value. In this case of course 0 is also an unacceptable result, so I use 1 as it seems harmless.
Also, a somewhat better math-based solution would be
if (mod(mobile_telephone1,1e10) - mod(mobile_telephone1,1e9) = 7e9) ...
Don't need to use log10s and such, just compare the modulos.

Related

libpqxx prepared statements nonnull checks for pointer types

I'm a newbie to SQL overall and libpqxx as well.I'm trying to build a basic application where I just need to use prepared statements to execute very simple jobs.
I have started with libpxx 4.0 version and I implemented codes like this:
pqxx::work txn( *conn );
auto result = txn.prepared( "my_insert" )( x->getId( ), x->isIdSet( ) )( x->getUser( ), x->isUserSet( ) )(x->getCreatedAt( ), x->isCreatedAtSet( ) ).exec( );
txn.commit();
Now I had to change to version 6.4 and realized the prepared function is deprecated and I should use the exec_prepared function. Okay. BUT I'm really missing the "nonnull" condition. For certain reasons I'm working with a lot of pointers and I need a convenient way to pass on these values to the database API. I could write something like:
auto result = txn.exec_prepared( "my_insert", (x->isIdSet() ? std::to_string(x-getId()) : "null"), ....);
This could work in some cases but when I try to insert "null" as string into a smallint field I get an sql error (what is reasonable though).
As types differ I can't use the ?: operator to return string/int/etc... on true branch and nullptr on false branch.
I couldn't find a proper documentation about the library. They have a doc here but if you want to find out more about a certain function there's literally nothing there.
Honestly even the deprecated .prepared(...) function doesn't work properly with 6.4 for me. I tried txn.prepared("whatever")(y->z->getA(), y->z != nullptr).exec() form and I got segmentation fault when y was a valid non-null pointer type and z was null-pointer. I expected the function wouldn't touch the value before checking on the condition but apparently it's not the case.
I have a prepared statement with 8 parameters 6 of them being a pointer type (shared_ptr) and it would be extremely messy if I have to come up with a ridiculous solution to check all the parameters one-by-one and having to write 200 lines just to be able to call this function properly.
Anyone out there having a proper solution? As I mentioned I'm a newbie so I might miss an important part there. Help me out please ^^
I know this question is old. But here's what you do:
const auto& id{ x->isIdSet()
? std::optional<std::string>{x-getId()} : std::nullopt };
auto result{ txn.exec_prepared("my_insert", id, ....) };

Can I stop the submitted statements on the first error?

Just for the debugging purpose: Is there a way to stop executing a series of submitted statements on the first error?
Let's say, I have three steps of code where the second statement has an error. Assume that I run all of them at once in the SAS window. Then, I expect SAS to successfully execute the first sentence and to stop working due to the error detected in the second sentence. Then I can easily go there to fix this.
But what's actually happening is that SAS tries to execute all three steps (i.e., 1st, 2nd (with error, though), and 3th). Hope that there is a solution for this.
Two remarks:
I found that the below code may help, but it didn't actually. Otherwise, please enlighten me.
options syntaxcheck dmssynchk;
I don't want to use the SAS option, errorabend because it shuts down SAS session itself. I just want my SAS stop "the submitted code" and want to fix the issue.
Thanks in advance.
There is a commonly used macro called %runquit that allows that... Not sure where it originates from, but here it goes:
%macro runquit;
; run; quit;
%if &syserr. ne 0 %then %do;
%abort cancel;
%end;
%mend runquit;
proc sort data=asdasd;
by _all_;
%runquit;
data abc;
a = 1;
b = 2;
c = 3;
%runquit;
The drawback is that you have to replace any run; or quit; statement with the call to %runquit, making the code less pretty.
A related StackOverflow question can be found here.
Also, see this discussion for other solutions.

What is the difference between keeping column on left of = in sql

I am reading someone else sql and his code was like this
There is view called user_v with column path as Array
select * from user_v where 'USER_TYPE'=path[2]
can't i use
path[2] = 'USER_TYPE'
This is a precaution taken by some programmers in languages where assignment and comparison can be easily confused, such as C or PHP, where the following statement looks innocent:
if ( $foo = 1 )
but it is actually assigning 1 to $foo, and the if will always evaluate to true (in PHP, at least, where 1 is true). What was meant was if ( $foo == 1 ).
If you reverse the arguments, the error becomes obvious sooner:
if ( 1 = $foo ) # SYNTAX ERROR
if ( 1 == $foo ) # Desired behaviour
This is sometimes known as "yoda coding", and is in the coding standards of Wordpress, for example.
See also: Why put the constant before the variable in a comparison?
In SQL, there is less chance of such a muddle, since although = can mean either assignment or comparison, there are rarely situations where a typo would select the wrong meaning.
However, if the coding standards for every other language used by a project mandate it, it would make sense to reinforce the habit by also using it in SQL, since I can't think of a specific reason not to write it that way.
There is no difference at all.
It's psychology.
You would want to read someone else's code out laud and say:
Where my column equals 2.
When you read:
Where 2 equals my column
you have to stop for a while, return, explain it to yourself.
We maintain all of these rules that seem rubish at first glance just to make other people lives easier.

ANTLR reports error and I think it should be able to resolve input with backtracking

I have a simple grammar that works for the most part, but at one place it reports error and I think it shouldn't, because it can be resolved using backtracking.
Here is the portion that is problematic.
command: object message_chain;
object: ID;
message_chain: unary_message_chain keyword_message?
| binary_message_chain keyword_message?
| keyword_message;
unary_message_chain: unary_message+;
binary_message_chain: binary_message+;
unary_message: ID;
binary_message: BINARY_OPERATOR object;
keyword_message: (ID ':' object)+;
This is simplified version, object is more complex (it can be result of other command, raw value and so on, but that part works fine). Problem is in message_chain, in first alternative. For input like obj unary1 unary2 it works fine, but for intput like obj unary1 unary2 keyword1:obj2 is trys to match keyword1 as unary message and fails when it reaches :. I would think that it this situation parser would backtrack and figure that there is : and recognize that that is keyword message.
If I make keyword message non-optional it works fine, but I need keyword message to be optional.
Parser finds keyword message if it is in second alternative (binary_message) and third alternative (just keyword_message). So something like this gives good results: 1 + 2 + 3 Keyword1:Value
What am I missing? Backtracking is set to true in options and it works fine in other cases in the same grammar.
Thanks.
This is not really a case for PEG-style backtracking, because upon failure that returns to decision points in uncompleted derivations only. For input obj unary1 unary2 keyword1:obj2, with a single token lookahead, keyword1 could be consumed by unary_message_chain. The failure may not occur before keyword_message, and next to be tried would be the second alternative of message_chain, i.e. binary_message_chain, thus missing the correct parse.
However as this grammar is LL(2), it should be possible to extend lookahead to avoid consuming keyword1 from within unary_message_chain. Have you tried explicitly setting k=2, without backtracking?

What is wrong with this SAS code?

I copy the code from a paper that i found on internet.
proc fcmp outlib=work.funcs.Test;
function whatAmI();
return(42);
endsub;
quit;
options cmplib=work.funcs;
data _null_;
rci = whatAmI();
put rci=; /* should be 42 */
run;
When I execute the code, it show the message:
ERROR 68-185: The function WHATAMI is unknown, or cannot be accessed.
I tried other functions and always show this message.
I change the libname, but nothing work.
What´s wrong?
I agree with Aditya.
Seems like 9.2 has the ability to actually use functions, while 9.1.3 only has the ability to more or less create them.
Check out THIS THREAD for more info.
Looks like a problem with the version. Make sure you are using SAS 9.2, since previous versions have a limited support of PROC FCMP.