I have a macro variable I need to use within PROC SQL. The way it resolves appears to have perfect syntax, but I am getting a syntax error and I'm not sure why;
%let test = mytext;
PROC SQL;
CREATE TABLE myTalbe&test AS
SELECT DISTINCT
a.column
FROM
tablename a
WHERE
a.column = %bquote('&test')
;QUIT;
The error I get throws a red line under the resolved text, 'mytext', and says
ERROR 22-322: Syntax error, expecting one of the following: a name, a
quoted string, a numeric constant, a datetime constant,
a missing value, (, *, +, -, ALL, ANY, BTRIM, CALCULATED, CASE, INPUT, PUT, SELECT, SOME, SUBSTRING, TRANSLATE,
USER.
I don't feel like this error applies here. If I hard code in 'mytext' it works fine. Am I missing something right under my nose? Can anyone lend me a hand?
Thanks!!!
The macro quoting is confusing the SAS parser. For this program I would remove the use of %bquote() and just use double quotes instead of single quotes so that the macro variable reference will resolve.
WHERE a.column = "&test"
If your are actually generating pass thru SQL into a system that requires the use of single quotes for string literals then you will need to use %unquote() to remove the macro quoting.
... from connection to ... ( ...
WHERE a.column = %unquote(%bquote('&test'))
... ) ...
The BQUOTE function tries to resolve the value immediately at execution time. Try removing it and using double quotes instead:
%let test = mytext;
PROC SQL;
CREATE TABLE myTalbe&test AS
SELECT DISTINCT
a.column
FROM
tablename a
WHERE
a.column = "&test"
;QUIT;
Related
I am a SAS Developer. I currently have a script that will read from a table column that is in datetime format. In this script, it looks something like this:
data a; batch_dttm = '01Jan2011:00:00:00'dt; run;
proc sql; select batch_dttm format=16.0 into:batch_dttm from a; quit;
So when I assign it to macro variable, it is actually assigning the value of 2930485 into batch_dttm.
The problem is, when I want to resolve this &batch_dttm in another job at a later stage, i have to use this:
input(&batch_dttm,16.0)
to convert 2930485 into date.
I don't want to resolve in this way as this is the only Macro variable that has to be resolved with this input function. I want to assign 01Jan2011:00:00:00 (as text?) in PROC SQL INTO statement so that i dont have to use input conversion anymore.
I want to call &batch_dttm as datetime format in another script. I only want to resolve the datetime using "&BATCH_DTTM"dt instead of input(&batch_dttm,16.0). I believe there is a step to convert 01Jan2011:00:00:00 into text without changing it to 2930485. Is there anyway to do so?
How can I add 1 more step to make me resolve the macro in below script:
"&batch_dttm"dt
Why do you think you need to add the INPUT() function? You can just use the value of the macro variable to generate the number of seconds, 2930485 in your example, into your code.
SAS stores datetime values as a number of seconds, so these two expressions are the same:
where batch_dttm = 2930485 ;
where batch_dttm = '01JAN2011:00:00:00'dt ;
Which means you can just use code like this to use your original macro variable.
where batch_dttm = &batch_dttm ;
If you do need to have the human friendly text in the macro variable, perhaps to use in a title statement, then just change the format you use when creating the macro variable.
select batch_dttm format=datetime20. into :batch_dttm trimmed ...
...
title "Data as of &batch_dttm";
where batch_dttm = "&batch_dttm"dt ;
You can also use %sysfunc() to call PUTN() to change the existing number of seconds into that style if you want.
select batch_dttm format=32. into :batch_dttm trimmed ...
...
title "Data as of %sysfunc(putn(&batch_dttm,datetime20.))";
where batch_dttm = &batch_dttm ;
Like this?
proc sql;
select put(batch_dttm, datetime20.) into:batch_dttm from a;
quit;
%put &batch_dttm;
I created a prompt in SAS EG that takes a text input and creates the macro variable called 'variableName'.
I am trying to reference this macro variable like so:
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = &variableName ;
This gives me an error that says: "Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, a missing value, BTRIM, INPUT, PUT, SUBSTRING, USER."
I have also tried enclosing &variableName in single and double quotes but when I do that I just don't get any results.
I am able to reference the prompt when I use query builder and filter data based on the prompt, but I am trying to use the prompt's value in calculated expressions, etc. and in queries I write without query builder. How can i reference the variable I created in the prompt??
Edit: code with a value that the macro variable would have
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = 'NAME OF PERSON';
When I run that, I get the results I want.
It needs to resolve to valid SAS code. Assuming &variableName is a string, then it would be something like:
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = "&variableName." ;
If this isn't working, please show a query that does work with the same value as the macro variable would have. And then we can suggest how to change your code.
Edit: based on your comment you do not have the prompt connected to your query. Right click the query and link the prompt to your query and it will run before the query to provide the value.
Trying to save data set Keepmerge as a permanent SAS data set called Oct15Tot using the code below. If I sub "&OutTabTot" for just Oct15Tot, it works. Trying to save myself from having to chang another bit of code further down (the %let is referenced at the beginning, and is used throughout my program. Thanks!
%let OutTabTot = Oct15Tot;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
data WorkItem."&OutTabTot";
set work.Keepmerge;
run;
Here's the error I'm getting:
22
201
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;,
_DATA_, _LAST_, _NULL_.
ERROR 201-322: The option is not recognized and will be ignored.
If you remove the quotes in your Data statement it should work, like so:
%let OutTabTot = Oct15Tot;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
Data WorkItem.&OutTabTot;
Set Work.Keepmerge;
Run;
In general, as cherry notes, you should just skip the quotations.
However, if you have reason to use quotations, you need to use an n afterwards to tell SAS to make this a name literal.
%let OutTabTot = Oct15 Tot;
options validmemname=extend;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
Data WorkItem."&OutTabTot"n;
Set Work.Keepmerge;
Run;
I don't recommend using things like dataset names with spaces if you can avoid it, as it's a pain... but it's legal, with options validmemname=extend set.
I'm not sure what's wrong with my code. The log is saying that the select has a syntax error which I copied below. How do I fix this?
"Syntax error, expecting one of the following: a quoted string, a numeric constant,a datetime constant, a missing value, +, -, MISSING, NULL, USER.
ERROR: Syntax error, statement will be ignored."
proc sql;
insert into orion.test (Fruits, Vegetables, Drinks, Meats)
values (select a.fruit, a.veggie, a.drink, a.meat FROM work.meals AS a);
quit;
This should be:
proc sql;
insert into orion.test (Fruits, Vegetables, Drinks, Meats)
select a.fruit, a.veggie, a.drink, a.meat FROM work.meals AS a;
quit;
In your original VALUES clause you can only use constants.
I am trying to write a program in SAS using the Prompt manager variable within a PROC SQL statement. It isnt working for me and keeps saying that the symbol is not recognized and will be ignored.
Heres a sample of my code...
LIBNAME mylib ORACLE SCHEMA = 'myschema' PATH = prd USER = 'admin' PASSWORD = 'admin12';
PROC SQL;
SELECT DISTINCT TEST_ID, COUNT(*), TERM
FROM mylib.testtable
WHERE RELEASE = 'PRETEST'
AND TEST_ID IN (&TEST) /* 'MATH', 'READING', 'SCIENCE' */
AND TERM = 'SPRING'
GROUP BY TEST_ID, TERM
ORDER BY TEST_ID, TERM;
QUIT;
And here is the problem in the log:
40 WHERE RELEASE = 'PRETEST'
41 AND TEST_ID IN (&TEST) /* 'MATH', 'READING', 'SCIENCE' */
NOTE: Line generated by the macro variable "TEST".
41 'MATH', 'READING', 'SCIENCE'
_
22
_
200
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant,
a missing value, (, -, SELECT.
ERROR 200-322: The symbol is not recognized and will be ignored.
My prompt variable is &TEST and should hold the list of tests to take but it dosent.
The issue here is one related to macro quoting. It's apparent that the token is enclosed in macro quotes (similar to %nrstr basically) for some reason, which cause it to work slightly differently than a normal %let. %unquote fixes it. I suspect there is also a better way to define the prompt to cause this not to occur, but I'm not completely sure - maybe one of the more experienced EG
folks can answer.
(Define a TEXT - SINGLE VALUE prompt called type and attach it to a program containing this:)
proc sql;
select name, age
from sashelp.class;
where name in (%unquote(&type.))
;
quit;
OK, I found a solution to my dilemma. As Joe stated, its a macro quoting issue, but it was also an array issue too. Both are solved by wrapping the variable in double quotes and some rudimentary replication.
Long story short,
the way SAS handles arrays and multiple values caused the first value to show only the first value so I had to assign multiple nullable values.
Working product below:
SELECT DISTINCT
TEST_ID, COUNT(*), TERM
FROM mylib.&TABLE
WHERE RELEASE IN ("&RELEASE", "&RELEASE1", "&RELEASE2", "&RELEASE3")
AND TEST_ID IN ("&TEST", "&TEST1", "&TEST2", "&TEST3", "&TEST4", "&TEST5")
AND TERM IN ("&TERM", "&TERM1", "&TERM2", "&TERM3", "&TERM4")
GROUP BY TEST_ID, TERM
ORDER BY TEST_ID, TERM;
Adding the &Release, &Release1, ect. allows multiple values to be captured should there be an array of values, otherwise it would accept the first value default the
extra values to null and throw a warning.
This was sufficient enough to be able to provide a list of options to the user and allow them to run using one or more parameter in each field