SP2-0042: unknown command "ENDD" - rest of line ignored - bash

I have script which is calling sqlplus to perform an operation. But, the sqlplus is returning this error always once the script is executed.
unknown command "ENDD" - rest of line ignored.
Here is my sql written inside the script :
map=sqlplus -s <<ENDD
$db_connection_string
SET BLANKLINES ON
SET VERIFY OFF HEADING OFF ECHO OFF FEEDBACK OFF
ALTER SESSION SET CURRENT_SCHEMA=$MY_DB;
select
TRIM(( select Col1 from tableA where tableB.col2=col2 and col3 = 100)) ||'#' ||
TRIM(tableB.col3 )||'#'||
tableB.col4 ||'#'||
tableB.col5 ||'#'||
tableB.col6 ||'#'||
TRIM(( select tableC.col1 from tableC WHERE tableC.col2=10050 AND tableC.col4 = 1 and tableC.col3 = tableB.col4)) AS ACT#TNID#INS#DC#CHNL#EXTSYSIDK
from tableB
where
tableB.col3='$evn'
and rownum <2;
ENDD

You're missing the command substitution syntax:
map=$(sqlplus -s <<ENDD
...
ENDD
)

Related

How to remove line number when you paste to sqlplus?

When I copy some lines of code and paste to sqlplus, it have line number for each line so the query would be invalid (see attached image).
Could anyone help me solve that: How to config so that after pasting the copied code, it has no line number in sqlplus?
try for your current sqlplus session before copypaste
set sqlprompt ''
set sqlnumber off
SQL*Plus® User's Guide and Reference
*SET SQLN[UMBER] {ON | OFF}
Sets the prompt for the second and subsequent lines of a SQL command or PL/SQL block.
*SET SQLP[ROMPT] {SQL> | text}
Sets the SQL*Plus command prompt.
example:
SQL> select *
from
dual
; 2 3 4
D
-
X
SQL> set sqlnumber off
SQL> set sqlprompt ''
select *
from
dual
;
D
-
X

How can i "Clean" output from sqlplus query?

i have got simple query and i need just one value from it = VALID
The query is:
select 'VALUE('||status||')' as value from user_indexes where index_name = '&1';
But i hve got in out:
C:\Program Files\zabbix\bin\win64\oracle>sqlplus -s #"C:\Program Files\zabbix\bi
n\win64\oracle\conn2.sql" OLAPTABLEVELSID
old 1: select status from user_indexes where index_name = '&1'
new 1: select status from user_indexes where index_name = 'OLAPTABLEVELSID'
VALID
What are this OLD and NEW strings? How can i dismiss it?
Thank you.
SET VERIFY OFF should help you. Please add such line in your script before query.
in sqplus you have substition variables. they are referenced by & or &&
when you run your script and pass it 'OLAPTABLEVELSID' - the query takes the '&1' and replaces it with ''OLAPTABLEVELSID'
SQL*Plus is telling you that in the output
SQL> set verify off
SQL> select '&1' from dual;
Enter value for 1: hello stackoverflow
'HELLOSTACKOVERFLOW
-------------------
hello stackoverflow
SQL>

How to call oracle merge into from shell script

I have one merge into statement and I'd like to execute it from shell script. Below is the merge into script.
MERGE INTO TESTA t USING TESTA_TEMP s ON
(
t.WAFER_ID = s.WAFER_ID
)
WHEN MATCHED THEN
UPDATE
SET
t.bin1 = s.bin1 WHEN NOT MATCHED THEN
INSERT
(
id,
bin1,
wafer_id
)
VALUES
(
s.id,
s.bin1,
s.wafer_id
);
It is working fine if I execute this in `sql plus manually. It shows below in the console.
4 rows merged.
SQL>
However, when I move this code in a shell script below, it won't work. Execute the shell script nothing happened, the console just shows the execution of shell script but never end.
#!/bin/sh
sqlplus -s user/pwd#sid <<END
SET serveroutput ON;
BEGIN
MERGE INTO TESTA t USING TESTA_TEMP s ON
(
t.WAFER_ID = s.WAFER_ID
)
WHEN MATCHED THEN
UPDATE
SET
t.bin1 = s.bin1 WHEN NOT MATCHED THEN
INSERT
(
id,
bin1,
wafer_id
)
VALUES
(
s.id,
s.bin1,
s.wafer_id
);
END;
/
END
I have also tried to replace this merge into statement with a simple inert statement, that was working. So is there any limitation call such merge into statement in a shell script? Anything wrong with my code?
Try the following:
#!/bin/sh
sqlplus -s user/pwd#sid <<EOF
set feed on
set pages 0
MERGE INTO TESTA t USING TESTA_TEMP s ON
(
t.WAFER_ID = s.WAFER_ID
)
WHEN MATCHED THEN
UPDATE
SET
t.bin1 = s.bin1 WHEN NOT MATCHED THEN
INSERT
(
id,
bin1,
wafer_id
)
VALUES
(
s.id,
s.bin1,
s.wafer_id
);
exit
EOF

bach echo variable substitution

I want make a query wiht this bash code.
##fist I will extrac the table name from table.txt file
table=$(head -n 1 tables.txt)
#In this code is where I will make the substitution on the query
result=`echo "select 'result '||segment_name||':'||MB||':'||TOTAL_MB from (
select TSEG.segment_name,round(TSEG.bytes/1024/1024) MB,l.segment_name as LSEGMENT_NAME,nvl(l.MB,0) as LOB_MB,nvl(l.MB,0)+round(TSEG.bytes/1024/1024) as TOTAL_MB
from dba_segments tseg, (select LOBS.table_name,round(bseg.bytes/1024/1024) MB,lobs.SEGMENT_NAME
from dba_lobs lobs,dba_segments bseg
where LOBS.SEGMENT_NAME=bseg.segment_name
order by bseg.bytes asc
) l
where TSEG.segment_type='TABLE'
and TSEG.segment_name='$table'
and TSEG.SEGMENT_NAME=l.table_name(+)
order by TOTAL_MB
)where rownum=1;`
my problem is on line TSEG.segment_name='$table', I need the table name on format 'TABLE_NAME'.
this is my actual ouput with table named "AABLG":
select 'result '||segment_name||':'||MB||':'||TOTAL_MB from (
select TSEG.segment_name,round(TSEG.bytes/1024/1024) MB,l.segment_name as LSEGMENT_NAME,nvl(l.MB,0) as LOB_MB,nvl(l.MB,0)+round(TSEG.bytes/1024/1024) as TOTAL_MB
from dba_segments tseg, (select LOBS.table_name,round(bseg.bytes/1024/1024) MB,lobs.SEGMENT_NAME
from dba_lobs lobs,dba_segments bseg
where LOBS.SEGMENT_NAME=bseg.segment_name
order by bseg.bytes asc
) l
where TSEG.segment_type='TABLE'
' and TSEG.segment_name='AABLG
and TSEG.SEGMENT_NAME=l.table_name(+)
order by TOTAL_MB
)where rownum=1;
you can see that the " ' " is on the first position, and I don't know why.
regards.
Marco.
This would be much better done without echo at all. Consider, for instance:
IFS=$'\r\n ' read -r table <tables.txt
IFS= read -r -d '' result <<EOF
select 'result '||segment_name||':'||MB||':'||TOTAL_MB from (
select TSEG.segment_name,round(TSEG.bytes/1024/1024) MB,l.segment_name as LSEGMENT_NAME,nvl(l.MB,0) as LOB_MB,nvl(l.MB,0)+round(TSEG.bytes/1024/1024) as TOTAL_MB
from dba_segments tseg, (select LOBS.table_name,round(bseg.bytes/1024/1024) MB,lobs.SEGMENT_NAME
from dba_lobs lobs,dba_segments bseg
where LOBS.SEGMENT_NAME=bseg.segment_name
order by bseg.bytes asc
) l
where TSEG.segment_type='TABLE'
and TSEG.segment_name='$table'
and TSEG.SEGMENT_NAME=l.table_name(+)
order by TOTAL_MB
) where rownum=1;
EOF
This also fixes the bug observed in your question by setting IFS to a value that includes $'\r', the carriage-return character found in DOS-formatted newlines, and thus stripping such characters when they exist at the end of the first line of tables.txt.

Table record count to unix log file

I need the count of records of a data base table from unix.
I am calling one sql script from unix and need the record count to any log file .
You can put the following into a test.sql file:
SET HEADING OFF;
SELECT COUNT(*) FROM dual;
QUIT;
and call it via SQL*Plus via script.
It will output:
1
since table dual has only one row. You should be able to write that into a log file.
You cant to append the output off your script to a named file by rediecting it like this.
$ sqlplus username/password#SID #your_script.sql >> /tmp/whatever.log
If your want to have more than a bald count in the output you'll need to include the boilerplate in the projectors:
SQL> select to_char(sysdate, 'YYYYMMDDHH24MISS')||'::Number of emps = '
2 , count(*)
3 from emp
4 group by to_char(sysdate, 'YYYYMMDDHH24MISS')||'::Number of emps = '
5 /
TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS COUNT(*)
--------------------------------- ----------
20100210133747::Number of emps = 16
SQL>

Resources