Please tell me how can i excute an oralce query inside a shell script.I am writing a shell script where I need to execute the oracle queries and scripts inside the shell script.
What is the purpose of these lines
sql_file=sachin.sql
cat <<!SQL > $sql_file
select $1 from dual;
exit;
!SQL
I think they are creating a new file, but what exactly is !SQL
It is the multi-line string terminator (a here-doc). There is no special meaning to the letters used, you could just as well have written !ORACLE, it just denotes that the content of the multi-line string are SQL commands.
What your script does is create a text file called sachin.sql with the contents specified between the two !SQL tokens.
PS: Not sure what shell this is for, my bash does not like the exclamation mark, thinks it is an event.
!SQL is just a token to notify the end of sql statements (here-doc) we can use any token like EOF, ENDSQL anything.
but the pre-requisite is the second token !SQL should start on the first column of the line.
Related
I'm running into an issue with command substitution that I'd like help with. I have a few processes that create a text file with commands that need to be executed.
File1.txt
Command_ID|Command_Name|Command
112121|Export XML Components|/Scripts/Export_XML.sh "Argument1" "Argument2"
112122|Test XML integrity|/Scripts/Test_XML.sh "Argument1" "Argument2" "Argument3"
My Script to execute these commands reads File1.txt and tries to execute the command in the third column using the following Command substitution. The goal here is to read and execute the commands sequentially and update a table with their return strings and return codes. I also have logic in the script to stop processing if a non-zero return code is encountered and store the current line number. This way the script can be restarted from the failed line after the issue has been addressed
VAR_File=/files/File1.txt
while IFS=$'|' read -r -a myArray
do
echo "${myArray[2]}"
VAR_Command="${myArray[2]}"
VAR_Return_String=$("${VAR_Command}")
VAR_Return_Code=$?
done < ${VAR_File}
The commands where the Arguments have double quotes are not being executed correctly.
What am I doing wrong and how can I fix this?
Thanks
In your script, VAR_Command is set to some string from File1.txt like /Scripts/Export_XML.sh "Argument1" "Argument2".
When running $(${VAR_Command}" with this string, the shell attempts to execute a script named Export_XML.sh "Argument1" "Argument2" (with quotes inside the file name), rather than the script Test_XML.sh to which the arguments "Argument1" and "Argument2" are passed.
If you remove the quotes by replacing $("${VAR_Command}") by $(${VAR_Command}), your code will work as expected.
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 am new to scripting in Linux and I think I'm getting confused with using variables inside command substitution the more I learn and read about it. Can someone explain to me the following scenario?
In my ksh script, I am trying to use a ksh variable inside an sqlplus script as follows:
temp_var="'a', 'b'"
randomVar=$(sqlplus -s $con_details <<EOF
update table ABC
Set field1='val'
Where field2 NOT IN ("${temp_var}");
EOF)
But the above syntax leads to an error in the query and it fails with code 1.
However when I unquote the variable and simply write
Where field2 NOT IN (${temp_var});
The query runs fine. I have seen a lot of examples on SO and Unix and Linux advising to always quote your variables used inside command substitution, but it seems the opposite works for me.
I don't seem to get why using quotes inside $() give an error as opposed to not using them.
Also, the query runs fine when I don't use the ksh variable in it (i.e. Without the WHERE clause).
This is a different situation than where the usual advice applies -- you're using the variable in a here-document, rather than as part of the command line. The difference is in how it gets parsed.
When you use a variable on a command line (something like ls $file), the variable gets replaced by its value partway through the process of parsing the command, with weird and generally undesirable results. The standard solution is to double-quote the variable (ls "$file") to prevent it from being parsed at all, just used directly. The standard mistake people make is putting quotes in the variable's value, which doesn't work because the variable gets replaced after quotes have already been parsed.
But you're using the variable in a here-document, and those work a lot differently. What happens is that the shell just does variable expansion (and some escape parsing) in the here-document, but doesn't do any more extensive parsing. In particular, it doesn't parse quotes in the here-document, just treats them like any other characters. The document then gets passed as input to the command (sqlplus in your case), and it parses the document according to whatever its syntax rules are. Since the parsing happens after variable replacement, it doesn't matter if the quotes are in the variable or around it; they work the same either way. But you can't do both, which is what was happening with double-quotes around the variable. Essentially, you were sending this document to sqlplus:
update table ABC
Set field1='val'
Where field2 NOT IN ("'a', 'b'");
... and sqlplus doesn't like that double-quotes around single-quotes thing, and complains.
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.
I have just started writing shell scripts. In if constructs, is the if considered to be a command or a keyword?
If it is a command, its path should be listed when searched through the which command. In reality, which does not find anything.
If if is not a command then ideally it does not need to be separated by a semicolon when then is written in the same line.
Can any of you please explain whether if is a command or a statement?
In bash if is a compound command (see "Shell Grammar" in the linked page.)
if is not a command it is the shell's construct.
Semicolon ; after condition is the shell syntax to terminate the condition and is required only when then keyword is on the same line. ; is not mandatory when then keyword appears on the next line.
So this will also work without semicolon and print date:
if ((RANDOM>0))
then
date
fi
if is a keyword. The semi-colon terminates the command that is between if and then.