I have set variables in my .sh file (ex. ENV=$1 RELEASE_ID=$2) within my.sh file. I sqlplus into my sql file like
sqlplus -S $username/password#destination #/path/copysetup/insert.sql
I want to pass variables ENV=$1 RELEASE_ID=$2 calling from a unix prompt into my sql file as
copysetup.sh env01 release 1.0
from my sql file I want to pass the same variable into an oracle table
insert into table...
Can someone assist on how to pass variable from bash shell script to sql file and ultimately insert the into my oracle table?
Pass the parameters on the command line:
sqlplus -S $username/password#destination #/path/copysetup/insert.sql $ENV $RELEASE_ID
then in the SQL script they become &1 and &2 (ensure you have set scan on at the top of the SQL script)
eg
set scan on
insert into foo (env, release) values ('&1', '&2');
commit;
Assuming your insert.sql file is the one which you'd like to insert an environment variable (or any bash variable), you can use sed to find/replace a some placeholder text with your desired value. For instance, if your insert.sql file looked something like
INSERT INTO #mytable VALUES (1,'sometext');
You could use sed to find/replace the #mytable string with the data stored in $MYVAR using the following syntax in a bash script
sed "s/#mytable/$MYVAR" insert.sql > modifiedinsert.sql
Now this would generate a new file, modifiedinsert.sql which you'd then pass into sqlplus.
Related
I'm using the following script to get the data of one of the variables from the database file
#!/bin/bash
sqlite3 pdu.db <<'END_SQL'
.timeout 2000
SELECT Variable_Value FROM Data Where Sr_No'7';
END_SQL
Now I wanted to store the output of the above commands in one variable. How we can store multiple commands output in one variable in the shell script?
There's no restriction against putting a multiline command inside a command substitution.
variable=$(sqlite3 /var/www/dbs/ha.db <<'END_SQL'
.timeout 2000
INSERT INTO table1 SELECT * FROM table2;
DELETE FROM table2;
END_SQL
)
I'm currently migrating AIX to Linux. The Oracle script contains a $ in the column name. While fetching through the shell script, I set the escape character to $, but it does not work. The query is like below:
Set escape $
Select c.logoff$time from temp c;
When run from shell script I'm getting "c.logoff invalid identifier".
How can I fix this?
This isn't an SQL*Plus (I assume that's your client) problem, so the set escape isn't doing anything - that's for escaping things SQL*Plus tries to interpret - see the docs.
This is a shell issue/feature. the $time part is being treated as a shell variable, and that doesn't exist, so the final table name doesn't have it. You can escape that at shell level, referring to \$time; e.g. if you're using a heredoc:
sqlplus -s -l usr/pass#db <<EOF
select c.logoff\$time from temp c;
EOF
I'm aware that the database engine itself is (often) on another machine and that SQL*Plus has no direct way of reading those environment variables, but I'm in a tricky situation where I merely need the environment variables from the machine the client itself is running on.
Is there a way to cheat these values into the SQL*Plus client from within a single script that will be run in SQL*Plus? The script consists of a single begin/end PL/SQL block, but if I need to use SQL*Plus directives of the set/define/variable sort that shouldn't be a problem either.
What I can't do is alter the way that the SQL*Plus executable itself is started (I don't have access to pass the values in as arguments).
Is there any way to accomplish this?
Note: dbms_system.get_env() seems to retrieve environment variables from the server itself, which is what I do not want.
You can get a few client-related things from the USERENV context, but not arbitrary environment variables.
If you can create a file on your local machine you could use the host command to set a substitution variable based on an environment variable:
SQL > host echo define homedir=$HOME > /tmp/gethome.sql
SQL > #/tmp/gethome.sql
SQL > host rm -f /tmp/gethome.sql
SQL > select '&homedir.' as home from dual;
HOME
------------
/home/apoole
1 row selected.
Not very pretty, but if you can't pass the variables on the command line as positional parameters then your options are rather limited.
This is using a Unix-y paths and commands of course, but you can do the same sort of thing in Windows.
Sys_context should solve your problem. You can set custom environment variable in database using DBMS_SESSION.SET_CONTEXT ('MY_NAMESPACE', 'MY_PARAMETER', v_input_parameter); and then fetch it using SYS_CONTEXT ('MY_NAMESPACE', 'MY_PARAMETER');
So you can run a initial pl/sql block to set variable in session and then use it as per requirement.
You can see an example here: http://blog.contractoracle.com/2010/03/using-dbmssessionsetcontext-to-store.html
If you could pass the variable via sqlplus argument passing mechanism. you could do the following,
cat > myscript.sql <<!
select '&1' as HOME from DUAL;
!
sqlplus user/pwd#db #myscript.sql $HOME
I am running a bash script that includes a here document, which calls SQLPLUS. This includes a .sql script to perform several grants. It works correctly without the substitution.
I want to be able to substitute in a bash variable into the grant statements. Is that possible?
This is a snippet from the bash script
CREDLINE=ownusr/ownpass
GRANT2DO=foo.sql
PASSPROC=bar <=== this is what I want to pass
sqlplus << EOQ11
$CREDLINE#chaos01
#$GRANT2DO
quit
EOQ11
This is a snippet from the foo.sql
grant execute on $PASSPROC to user86;
grant execute on $PASSPROC to user99;
I have tried several variations on $VAR and &1, but none has worked so far.
You have to call the sql-script with the value of what you want to pass
from sqlplus execute the script:
#foo.sql bar
in foo.sql use:
grant execute on &1 to usr
You can make your script create .sql file instead of having it replace existing one. Then pass it to sqlplus like you already do.
To make the script readable, you can use so-called "here documents" syntax, which is described here and which you are seemingly already familiar with.
If you insist on doing actual substitution, you could copy the template .sql to some temporary file and run sed -i on it with proper arguments to replace the variables. That, however, is much more complicated than the approach above.
How do I create a flat file with values fetched from a database ( using select ) in UNIX?
If you're using SQLPlus, use the SPOOL directive to output script output to a file. This SO question details how to get a CSV file via SQLPlus/SPOOL, for example.
SPOOL your_file.txt
SELECT 1, 'test'
FROM DUAL
SPOOL OFF
Related:
Oracle/PLSQL: Execute an SQL script file in SQLPlus
You should be able to call sqlplus from within a shell script, and pipe the results to a flat file. See this answer for details.
For variables passed to a shell script try a here document:
#!/bin/ksh
var=$(printf "'%s'" `date +%b-%d-%Y`)
sqlplus -s me/mtpasswd#mydbname <<!
set pages 55
spool outfile.lis
select * from mytable where sales_date= $var ;
spool off
!
This uses todays date. The flat file is outfile.lis