shell script to pass table name as a parameter in sqlplus? - shell

I have a file called table.txt which stores the table names. I want the sql update query to take the table name one by one from my table.txt file. My code is as follows:
while read LINE1; do
`sqlplus username/pwd#tname <<END |sed '/^$/d'
set head off;
set feedback off;
update &LINE1 set enterprise_id = '1234567890' where enterprise_id is NULL;
update &LINE1 set sim_inventory_id ='1234567890';
COMMIT;
exit;
END`
done < table.txt
it gives an error sqlplus not found. Can you please tell what is wrong?

This is nothing to do with passing the table names. The "sqlplus not found" error means it cannot find that binary executable, so it isn't getting as far as trying to connect or run the SQL commands.
Your shell script can only see environment variables from the calling shell if they were exported. If you've modified your PATH to include the location of the sqlplus binary then you may not have exported it; add export PATH after you set it.
Or you can set the script up to not rely on the shell environment.
export ORACLE_HOME=/path/to/oracle/installation
export PATH=${ORACLE_HOME}/bin:$PATH
export LD_LIBRARY_PATH=${ORACLE}/lib:${LD_LIBRARY_PATH}
while read LINE1; do
sqlplus username/pwd#tname <<END |sed '/^$/d'
set head off;
set feedback off;
update &LINE1 set enterprise_id = '1234567890' where enterprise_id is NULL;
update &LINE1 set sim_inventory_id ='1234567890';
COMMIT;
exit;
END
done < table.txt
Incidentally, updating the same table twice isn't necessary; you could do:
update &LINE1 set enterprise_id = nvl(enterprise_id, '1234567890'),
sim_inventory_id ='1234567890';
It would also be quicker to create a list of all the update statements from your file contents and run them all in a single SQL*Plus session, so you aren't repeatedly creating and tearing down connections. But that's outside the scope of what you asked.

Related

how to use batch script to export data from oracle into excel file with column names

This is my bat script:
set linesize 4000 pagesize 0 colsep ','
set heading off feedback off verify off trimspool on trimout on
spool &1
select *
from siebel.s_contact;
spool off
exit;
Then I try to run below command. I can generate a Excel file with data but column names are missing.
C:\Users\jy70606\Documents\Script>sqlplus -s geneos/password#database #C:\Users\jy
70606\Documents\Script\daily.sql daily.csv
My question is, how to make the columns available in my Excel?
Your Bat Script contains the following command to remove the columns
set heading off
You need to switch it on
set heading on
Reference: https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12040.htm#i2699001

Oracle/SQL PLUS: How to spool a log and write intermittently throughout script

Figuring out how to spool to a file has been easy enough. I am hoping there is an option to write to the text file after each command is written. I am not sure how to communicate the status of a long script to other people on my team. The solution we were going for was to write a log file to a network drive, as the script executes they would be able to follow along.
However, this seems to only write output to the file after the spool off; command at the end of the file.
Is there any way to achieve what we're trying to do, either with spooling a log file or another method?
Here is the code I have so far.
set timing on;
set echo on;
column date_column new_value today_var
select to_char(current_timestamp, 'yyyymmdd_HH24_MI') as date_column
from dual
/
select current_timestamp from dual;
SPOOL 'Z:\log\KPI\secondary_reporting_&today_var..log'
... lots of stuff...
spool off;
As far as I know there's no way to control when spooled output is written to a file. One way around this, though, could be to abandon spooling altogether and just redirect the output:
$ sqlplus #/path/to/script.sql >& /path/to/script.log
Two methods come to mind, depending on what your 'stuff' is.
1) If your code has lots of SQL statements and PL/SQL blocks then you can repeatedly spool for a little while. Use the spool <filename> append statement for this.
SQL> help spool
SPOOL
-----
Stores query results in a file, or optionally sends the file to a printer.
In iSQL*Plus, use the Preferences screen to direct output to a file.
SPO[OL] [file_name[.ext] [CRE[ATE] | REP[LACE] | APP[END]] | OFF | OUT]
Not available in iSQL*Plus
2) If you have long running PL/SQL procedures use the UTL_FILE package. See https://docs.oracle.com/html/B14258_02/u_file.htm for more information. This does require some setup and administrative privileges in the database to set up a directory where writing is allowed.

.sql file not returning the column headers in csv file

The below code is in batch file script(.bat file) which calls the sql file.
del C:\SREE\csvfile.csv
sqlplus SERVERNAME/Test123#ldptstb #C:\SREE\sree.sql
set from_email="SENDER_EMAIL_ID"
set to_email="TO_EMAIL_ID"
set cc_email="CC_EMAIL_ID"
set email_message="Csv file from application server"
set body_email=C:\SREE\sree.txt
set sendmail=C:\Interface\sqlldr\common\SENDMAIL.VBS
set interface_log=C:\SREE\csvfile.csv
cscript %sendmail% -F %from_email% -T %to_email% -C %cc_email% -S %email_message% -B %body_email% -A %interface_log% -O "ATTACHFILE" -A %body_email% -O "FILEASTEXT"
exit
This below content in .sql file code which executes the SQL Query and stores the data into csv file:
set pagesize 0
set heading on
set feedback off
set trimspool on
set linesize 32767
set termout off
set verify off
set colsep ","
spool C:\SREE\csvfile.csv
SELECT Name, ID, Email, Role, Status FROM csvfile
exit
The output is stored in csv file and getting this file in email.
But theproblem is I am not getting the Column Names in the csv file. I had tried in many scenarios to get the names as a cloumn headings in csv file.
Anyone please help me out with the code to get the column names in the csv file.. thanks in advance...
When you set pagesize 0 headings are suppressed:
SET PAGES[IZE] {14 | n}
Sets the number of lines on each page of output. You can set PAGESIZE to zero to suppress all headings, page breaks, titles, the initial blank line, and other formatting information.
That's the case even if you then explicitly set headings on.
You can either set pagesize to something very large instead, or possibly more helpfully as you probably don't really want the separator line of dashes, generate them yourself with:
PROMPT Name,ID,Email,Role,Status
... before your select statement.
Use GENERATE_HEADER configuration setting amd set it to Yes like
SET GENERATE_HEADER = 'Yes'
See this related thread here https://community.oracle.com/thread/2325171?start=0&tstart=0

How to skip row when importing bad MySQL dump

Given bad mysqldump that causes error on import:
namtar backups # mysql -p < 2010-12-01.sql
Enter password:
ERROR 1062 (23000) at line 8020: Duplicate entry 'l�he?' for key 'wrd_txt'
Is there an easy way to tell import to just skip given row and continue?
(Yes, I know I can manually edit the file or parse output, but it's not very convinient)
If you can make the dump again you could add --insert-ignore to the command-line when dumping.
Or you can try using the mysqlimport command with --force,which will continue even if it encounters MySQL Errors.
mysql -f -p < 2010-12-01.sql
the -f (force) being the operative option here, worked for me.
Following the advice from jmlsteele's answer and comment, here's how to turn the inserts into INSERT IGNORE on the fly.
If you're importing from an sql file:
sed -e "s/^INSERT INTO/INSERT IGNORE INTO/" < 2010-12-01.sql | mysql -p
If you're importing from a gz file, just pipe the output from gunzip into sed instead of using the file input:
gunzip < 2010-12-01.sql.gz | sed -e "s/^INSERT INTO/INSERT IGNORE INTO/" | mysql -p
Great tip. I did it a little different but same result.
perl -pi -e 's/INSERT INTO/INSERT IGNORE INTO/g' filename.sql
The other options certainly are viable options, but another solution would be to simply edit the .sql file obtained from the mysqldump.
Change:
INSERT INTO table_name ...
TO
INSERT IGNORE INTO table_name ...
Just a thought did you delete the MySQL directives at the top of dump?
(I unintentionally did when I restarted a restore after deleting all the records/tables I'd already inserted with a sed command). These directives tell MySQL ,among other things, not to do unique tests, foreign key tests etc)
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET #OLD_TIME_ZONE=##TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0 */;

How to append system time to the file name in oracle?

I am very new to oracle.I need to create a file with the system timestamp from oracle. Please let me know how do i do that.
More over I need to write any exceptions or errors thrown by my pl/sql code to a file and exit after an error. How do i do this?
Thanks,
Priya.R
It seems you want to look into the UTL_FILE Oracle supplied package, as you're trying to use PL/SQL to create the file.
You can generate the file this way:
(You'll need to create an Oracle DIRECTORY first, pointing to the OS location of the file:
CREATE OR REPLACE DIRECTORY DIR AS 'your OS directory';
Note that the name 'DIR' is used in the sample code that follows. You will also require the CREATE DIRECTORY privilege, and then grant read and write permissions on the directory to the user who will use it:
GRANT READ,WRITE ON DIR TO user1;
)
DECLARE
v_logfile VARCHAR2(100);
v_FH UTL_FILE.FILE_TYPE;
BEGIN
v_logfile := TO_CHAR(SYSDATE,'YYYYMMDD HH24MISS')||'_process.log';
v_FH := UTL_FILE.FOPEN(DIR, v_logfile, 'w');
UTL_FILE.PUTLINE(v_FH, 'Some text on a new line');
UTL_FILE.FCLOSE(v_FH);
END;
This is how you can get a dynamic filename in SQL Plus
SET TERMOUT OFF
DEFINE dynamic_filename = idle
COLUMN which_dynamic NEW_VALUE dynamic_filename
SELECT 'prefix_'
||TO_CHAR( SYSDATE, 'YYYYMMDD' )
||'_'
||TO_CHAR( SYSDATE, 'HH24MISS' )
||'.log' which_dynamic
FROM dual;
SET TERMOUT ON
SPOOL &dynamic_filename
SELECT * FROM dual;
SPOOL OFF
The file gets created in the default directory for SQL Plus (on windows this is the "Start In:" property of the shortcut)
To place the output in a known directory amend the SPOOL command to something like...
SPOOL c:\output_dir\&dynamic_filename
To get an SQL Plus script to exit after an error then include this command...
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK

Resources