How to set default value for missing substitution parameter - oracle

I'm calling a procedure in a script and passing variables like this:
##./procedudure.sql 'var1' 'var2' 'var3'
In the procedure I'm using the values like this:
DEFINE variable1 = '&1'
DEFINE variable2 = '&2'
DEFINE variable3 = '&3'
...
insert into TABLE (id, text) values ('&varibale1', '&variable2&variable3')
I want to be able to call the procedure with only two parameters instead of 3 so that the last one is replaced with empty string. But when I call it like this, I get this prompt:
Enter value for 3:
I've also tried to use the parameters like this, but with the same result:
DEFINE variable2 = '&2' || '&3'
I've found this page for using prompt for missing variable, but couldn't find anywhere how to set a default value: https://blogs.oracle.com/opal/entry/sqlplus_101_substitution_varia#9_14
As you can see from the code, I want the last parameters to be concatenated. This should be a workaround for 240-character limit.

Well yes I see it's old but... until now, unanswered!
OP, this is what you're looking for but it's not exactly simple!
I originally spotted the technique on Tanel Poder's website but not sure if he came up with it or not.
Anyway, here I'm using it to setup defaults in case warning and critical limits are not passed in to the script.
rem setup default values
def DEFAULT_WARN_LEVEL='97'
def DEFAULT_CRIT_LEVEL='99'
rem trick to assign values to &1 and &2 so that SQL*Plus does not ask
col warn_level new_value 1
col crit_level new_value 2
select null warn_level
, null crit_level
from dual
where 1=2
/
rem if values were passed in, use them, if not, use the defaults
select nvl('&1','&DEFAULT_WARN_LEVEL') warn_level
, nvl('&2','&DEFAULT_CRIT_LEVEL') crit_level
from dual
/
rem the values, either passed in or defaults are now in &1 and &2
rem put the values in meaningful variables
def warn_level='&1'
def crit_level='&2'

When you code it as DEFINE variable3 = '&3' in your procedure, the system thinks 3 is variable and it will always prompt for its value.
In case you want to pass a default value for 3, you should do DEFINE 3 = YOUR_VALUE_FOR_PARAM_3

In the example link, section 9.14, I don't see where he uses any default value. He just either asks for it, or takes the parameter. SQLPLUS always is going to ask for any &1, &2, .. he sees in your file, if it is not given as input parameter. No matter how and where you use it. It's not like in Bash, where he just replaces $1 with null, and doesn't do anything. I don't think you can disable the auto-asking in SQLPLUS.

Related

Call Incremental Datasets Created by Macro Function

I have a macro variable called max_attempts I created from a a PROC SQL that equals 4 for my current datafile. Then, I used a macro function to create datasets up to max_attempts so now I have attempt1_table, attempt2_table, attempt3_table, and attempt4_table. Now I'm having trouble merging the 4 datasets.
data final_table;
set attempt1_table - attempt&max_attempts._table;
run;
The inputted datafile will have a different max_n each time, so I'm using macros to account for that.
The - shortcut only works if the number is at the end of the dataset name. Rename your datasets to be round_table1, round_table2, etc.:
data final_table;
set round_table1 - round_table&max_n.;
run;
Use the trimmed option of the into :macrovar clause in order to remove the leading spaces that cause set attempt1_table - attempt&max_attempts._table; to resolve into erroneous syntax.
Example:
proc sql noprint;
select <computation-for-max-attempts>
into :max_attempts trimmed /* removes leading spaces when column is numeric */
from ...
;
quit;
Thank you everyone for your help! It was two issues, the number has to be at the end of the dataset name when using the - shortcut and using trimmed to remove leading spaces.
proc sql feedback;
select max(max_attempts)
into: max_attempts trimmed
from analysis_data;
quit;
data analysis_table;
set unknown_table attempt_table1 - attempt_table&max_attempts;
run;

How can I use 'update where' select in FoxPro?

I am totally new to FoxPro (and quite fluent with MySQL).
I am trying to execute this query in FoxPro:
update expertcorr_memoinv.dbf set 'Memo' = (select 'Memo' from expertcorr_memoinv.dbf WHERE Keymemo='10045223') WHERE Keydoc like "UBOA"
I got the error:
function name is missing )
How can I fix it?
In FoxPro SQL statements you would not 'single-quote' column names. In Visual FoxPro version 9 the following sequence would run without errors:
CREATE TABLE expertcorr_memoinv (keydoc Char(20), keymemo M, Memo M)
Update expertcorr_memoinv.dbf set Memo = (select Memo from expertcorr_memoinv.dbf WHERE Keymemo='10045223') WHERE Keydoc like "UBOA"
If you would provide a few sample data and an expected result, we could see whether the line you posted would do what you want after correcting the single-quoted 'Memo' names.
NB 1: "Memo" is a reserved word in FoxPro.
NB 2: As you know, the ";" semicolon is a line-continuation in Visual FoxPro, so that a longer SQL statement can be full; of; those;
So that the Update one-liner could be written as:
Update expertcorr_memoinv ;
Set Memo = (Select Memo From expertcorr_memoinv ;
WHERE Keymemo='10045223') ;
WHERE Keydoc Like "UBOA"
NB 3: Alternatively, you can SQL Update .... From... in Visual FoxPro, similar to the Microsoft SQL Server feature. See How do I UPDATE from a SELECT in SQL Server?
I would do that just as Stefan showed.
In VFP, you also have a chance to use non-SQL statements which make it easier to express yourself. From your code it feels like KeyMemo is a unique field:
* Get the Memo value into an array
* where KeyMemo = '10045223'
* or use that as a variable also
local lcKey
lcKey = '10045223'
Select Memo From expertcorr_memoinv ;
WHERE Keymemo=m.lcKey ;
into array laMemo
* Update with that value
Update expertcorr_memoinv ;
Set Memo = laMemo[1] ;
WHERE Keydoc Like "UBOA"
This is only for divide & conquer strategy that one may find easier to follow. Other than that writing it with a single SQL is just fine.
PS: In VFP you don't use backticks at all.
Single quotes, double quotes and opening closing square brackets are not used as identifiers but all those three are used for string literals.
'This is a string literal'
"This is a string literal"
[This is a string literal]
"My name is John O'hara"
'We need 3.5" disk'
[Put 3.5" disk into John's computer]
There are subtle differences between them, which I think is an advanced topic and that you may never need to know.
Also [] is used for array indexer.
Any one of them could also be used for things like table name, alias name, file name ... (name expression) - still they are string literals, parentheses make it a name expression. ie:
select * from ('MyTable') ...
copy to ("c:\my folder\my file.txt") type delimited

Change value psql where value between, as string

I have a query that must set a value if the number is between 2 values, but the output is not ok, I think because that column is a string. Any way to do it even it's string?
(In output I have value as , 5 witch is not ok).
All the values that are incorrect are Integer.
SET lkp_age_category_id = 7
WHERE
age BETWEEN '26' and '35.99';
I guess, only working on the SQL side, you could cast the values right into the query, e.g.:
SET lkp_age_category_id = 7
WHERE age BETWEEN '26'::float AND '35.99'::float;
Also check this answer https://stackoverflow.com/a/13809603/917617.

In TI-BASIC, how do I display the Variable Name given only the variable?

I'm creating a function that displays a lot of variables with the format Variable + Variable Name.
Define LibPub out(list)=
Func
Local X
for x,1,dim(list)
list[x]->name // How can I get the variable name here?
Disp name+list[x]
EndFor
Return 1
EndFunc
Given a list value, there is no way to find its name.
Consider this example:
a:={1,2,3,4}
b:=a ; this stores {1,2,3,4} in b
out(b)
Line 1: First the value {1,2,3,4} is created. Then an variable with name a is created and its value is set to {1,2,3,4}.
Line 2: The expression a is evaluated; the result is {1,2,3,4}. A new variable with the name b is created and its value is set to `{1,2,3,4}.
Line 3: The expression b is evaluated. The variable reference looks up what value is stored in b. The result is {1,2,3,4}. This value is then passed to the function out.
The function out receives the value {1,2,3,4}. Given the value, there is no way of knowing whether the value happened to be stored in a variable. Here the value is stored in both a and b.
However we can also look at out({1,1,1,1}+{0,2,3,4}).
The system will evaluate {1,1,1,1}+{0,2,3,4} and get {1,2,3,4}. Then out is called. The value out received the result of an expression, but an equivalent value happens to be stored in a and b. This means that the values doesn't have a name.
In general: Variables have a name and a value. Values don't have names.
If you need to print a name, then look into strings.
This will be memory intensive, but you could keep a string of variable names, and separate each name by some number of characters and get a substring based on the index of the variable in the list that you want to get. For instance, say you want to access index zero, then you take a substring starting at (index of variable * length of variable name, indexofvariable *length + length+1).
The string will be like this: say you had the variables foo, bas, random, impetus
the string will be stored like so: "foo bas random impetus "

SAS format procedure, invalue statement ,UPCASE option does not work

I need to create SAS informat that will change all case versions of 'Male' and 'Female' to digits.
I found in the documentation that there is UPCASE options that does the job. "converts all raw data values to uppercase before they are compared to the possible ranges. If you use UPCASE, then make sure the values or ranges you specify are in uppercase"
Unfortunately after adding the UPCASE option none of the input values is read properly.
The SAS version id 9.2.
My code is below.
options fmtsearch=(WORK);
proc format lib=WORK;
invalue gender UPCASE
MALE = 1
FEMALE = 2
;run;
data _null_;
q='MALE';
x=input(q,gender.);
put q=;
put x=;
run;
The log is:
NOTE: Invalid argument to function INPUT at line 186 column 7.
q=MALE
x=.
q=MALE x=. _ERROR_=1 _N_=1
What is the proper usage of this option?
Very simple, just put UPCASE inside brackets...

Resources