Run .sql files in sequence on sqlplus - sql

We have multiple .sql files and is there any way we can run them in single job ?
Sample files.
#task1.sql ;
#task2.sql ;
#task3.sql ;
Is there any way can I put all 3 above files in single files and run?

Well ... yes.
task_main.sql:
#task1.sql
#task2.sql
task1.sql:
select deptno, ename, job, sal
from emp
where deptno = 10;
task2.sql:
select * from dept;
Running task_main from SQL*Plus:
SQL> #task_main
DEPTNO ENAME JOB SAL
---------- ---------- --------- ----------
10 CLARK MANAGER 2450
10 KING PRESIDENT 5000
10 MILLER CLERK 1300
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>

Related

What's the meaning of this Oracle SQL code?

I've been learning Oracle SQL recently and I came across the following code:
SELECT *
FROM employees outer_emps
WHERE (2-1) = (
SELECT COUNT(*)
FROM employees inner_emps
WHERE inner_emps.salary > outer_emps.salary
);
Could someone please help me understand the syntax?
It returns employees whose salary is the 2nd highest.
For example:
SQL> select ename, sal from emp order by sal;
ENAME SAL
---------- ----------
SMITH 840
JAMES 950
ADAMS 1100
WARD 1250
MARTIN 1250
MILLER 1300
TURNER 1500
ALLEN 1600
CLARK 2450
BLAKE 2850
JONES 2975
SCOTT 3000 --> SCOTT and FORD have the 2nd highest salary
FORD 3000 -->
KING 5000 --> KING has the highest salary
14 rows selected.
SQL> select ename, sal
2 from emp outer_emps
3 where 1 = (select count(*) from emp inner_emps
4 where inner_emps.sal > outer_emps.sal);
ENAME SAL
---------- ----------
SCOTT 3000
FORD 3000
SQL>
If you used <, you'd get the 2nd lowest salary (that's James because SMITH's salary is 840 - the lowest - and JAMES follows with 950):
SQL> select ename, sal
2 from emp outer_emps
3 where 1 = (select count(*) from emp inner_emps
4 where inner_emps.sal < outer_emps.sal);
ENAME SAL
---------- ----------
JAMES 950
SQL>
I'd probably do it as follows; that's easier to understand:
SQL> with temp as
2 (select ename, sal,
3 rank() over (order by sal desc) rnk
4 from emp
5 )
6 select ename,sal from temp
7 where rnk = 2;
ENAME SAL
---------- ----------
SCOTT 3000
FORD 3000
SQL>

Make a Report that Can Edit another Report in APEX

I have multiple report pages. I am working on a system that stores a lot of data. Is it possible to have reports that are able to have column edited on two different reports?
i.e. Not all the information may be relevant to the person entering data on the interactive grid. So I would have a condensed version of the report where the would be able to enter the data you are responsible for. But the report would still display the information entered on the condensed report version.
I'd think of a view and its instead of trigger.
Here's an example; see if you can adjust it to interactive grid. It is based on Scott's sample EMP and DEPT tables.
First, a view that joins these two tables:
SQL> create or replace view v_emp_dept as
2 select d.deptno, d.dname, e.empno, e.ename, e.job, e.sal
3 from emp e join dept d on d.deptno = e.deptno;
View created.
Instead of trigger; it fires when you update the view, but in the background it modifies data in view's underlying tables:
SQL> create or replace trigger trg_iu_ved
2 instead of update on v_emp_dept
3 for each row
4 begin
5 update dept d set
6 d.dname = :new.dname
7 where d.deptno = :new.deptno;
8
9 update emp e set
10 e.ename = :new.ename,
11 e.job = :new.job,
12 e.sal = :new.sal
13 where e.empno = :new.empno;
14 end;
15 /
Trigger created.
OK, let's test it. Sample data:
SQL> select * from v_emp_dept where deptno = 10;
DEPTNO DNAME EMPNO ENAME JOB SAL
---------- -------------- ---------- ---------- --------- ----------
10 ACCOUNTING 7782 CLARK MANAGER 2818
10 ACCOUNTING 7839 KING PRESIDENT 5750
10 ACCOUNTING 7934 MILLER CLERK 1495
Update some values:
SQL> update v_emp_dept set
2 dname = 'Accounting',
3 ename = initcap(ename),
4 sal = sal * 10
5 where deptno = 10;
3 rows updated.
Oracle says that 3 rows were updated:
SQL> select * from v_emp_dept where deptno = 10;
DEPTNO DNAME EMPNO ENAME JOB SAL
---------- -------------- ---------- ---------- --------- ----------
10 Accounting 7782 Clark MANAGER 28180
10 Accounting 7839 King PRESIDENT 57500
10 Accounting 7934 Miller CLERK 14950
The view looks OK. What about EMP and DEPT tables?
SQL> select * from dept where deptno = 10;
DEPTNO DNAME LOC
---------- -------------- -------------
10 Accounting NEW YORK
SQL> select empno, ename, job, sal from emp where deptno = 10;
EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7782 Clark MANAGER 28180
7839 King PRESIDENT 57500
7934 Miller CLERK 14950
SQL>
Right; data has been changed in these two tables as well.

Use substitution variable within Oracle IN clause

I'm trying to write a simple query where the requirement is to use a substitution variable that can be used to enter mutiple possible values for a column that's used for filtering the query.
The reqiurement is to produce the following query
select
CONTRACT,
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER
where state='Picked'
and contract in ('ABC','DEF')
but the contract values will need to be entered during runtime by means of a substitution variable. I'm working with the limitation of only being able to write a static SQL Query ("select ..from..where..") and no dynamic code can be written inside pl sql blocks.
So, what I tried was the following,
select
CONTRACT,
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER_JOIN
where contract in (select '''' || REPLACE('&CONTRACT',';',''',''') || '''' from dual)
When the prompt appears for the substitution, I enter ABC;DEF
But this doesn't seem to work. Although when I run the following separately,
select '''' || REPLACE('&CONTRACT',';',''',''') || '''' from dual
I get 'ABC','DEF' as the result.
Why is this not working? Is there a way to achieve my desired result ?
Thanks
One option is to split those values into rows and use them as a subquery.
Example based on Scott's EMP table:
SQL> select ename, job, sal from emp;
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
WARD SALESMAN 1250
JONES MANAGER 2975
MARTIN SALESMAN 1250
BLAKE MANAGER 2850
CLARK MANAGER 2450
SCOTT ANALYST 3000
KING PRESIDENT 10000
TURNER SALESMAN 1500
ADAMS CLERK 1100
JAMES CLERK 950
FORD ANALYST 3000
MILLER CLERK 1300
14 rows selected.
SQL> select ename, job, sal
2 from emp
3 where ename in (select regexp_substr(replace(q'[&&par_ename]', chr(39), ''), '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count(q'[&&par_ename]', ',') + 1
6 );
Enter value for par_ename: 'SMITH','ALLEN'
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
SQL>
Alternatively, use sys.odcivarchar2list:
SQL> select ename, job, sal
2 from emp
3 where ename in (select column_value
4 from table(sys.odcivarchar2list(&par_ename))
5 );
Enter value for par_ename: 'SMITH','ALLEN'
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
SQL>
It works without single quotes as well:
SQL> Select ename, job, sal
2 from emp
3 where ename in (select regexp_substr(replace(q'[&&par_ename]', chr(39), ''), '[^,]+', 1, level)
4 from dual
5 connect by level <= regexp_count(q'[&&par_ename]', ',') + 1
6 );
Enter value for par_ename: SMITH,ALLEN,KING
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
KING PRESIDENT 10000
SQL>

Cannot use variable in select statement [duplicate]

This question already has answers here:
How do I use variables in Oracle SQL Developer?
(10 answers)
Closed 2 years ago.
I need just use var as some value in Oracle SQL, something like this:
date = '21-Sep-10'
SELECT *
FROM (
SELECT *
FROM table2
WHERE some_date = date
) table1
WHERE table1.due_date = date;
How I can do this properly ?
Thanks !
It depends on tool you use. In SQL*Plus, you'd precede it with &
SELECT * FROM table WHERE id = &tmp;
In some other tools (SQL Developer, TOAD), that would be :
SELECT * FROM table WHERE id = :tmp;
If you're using the same variable more than once in the same query, precede it with two ampersands:
SQL> set linesize 200
SQL> set ver off
SQL> select *
2 from (select *
3 from emp
4 where deptno = &&deptno
5 )
6 where deptno = &&deptno;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09.06.81 2450 10
7839 KING PRESIDENT 17.11.81 5000 10
7934 MILLER CLERK 7782 23.01.82 1300 10
SQL>
However, if you run the same query once again, you won't be prompted for the variable (as it is "remembered"):
SQL> /
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 09.06.81 2450 10
7839 KING PRESIDENT 17.11.81 5000 10
7934 MILLER CLERK 7782 23.01.82 1300 10
SQL>
You'll need to undefine it first:
SQL> undefine deptno
SQL> /
Enter value for deptno: 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17.12.80 800 20
7566 JONES MANAGER 7839 02.04.81 2975 20
7788 SCOTT ANALYST 7566 09.12.82 3000 20
7876 ADAMS CLERK 7788 12.01.83 1100 20
7902 FORD ANALYST 7566 03.12.81 3000 20
SQL>

Oracle: Overwrite values in a column with the longest string

I’m running into a problem.
Say, I have columns called “C1, C2, C3....” in a table. I’d like to use the longest string in C1 to replace every other cells in C1 column without disturbing other columns.
I tired several ways but I cannot get my Oracle code run. Could someone please show me a sample code to do this problem? I typed my question using a cellphone so I apologize for not showing you my code. But I think my description is fine... Thank you!
I would use window functions. Oracle has a very convenient functionality with keep:
select max(col1) keep (dense_rank first order by len(col1) desc) over () as col1,
col2, col3, . . .
from t;
You can incorporate this into an update:
update t
set col1 = (select select max(col1) keep (dense_rank first order by len(col1) desc) over () as col1
from t
);
For example:
SQL> select * from test;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> update test set
2 dname = (select max(dname) --> MAX fixes TOO-MANY-ROWS because ACCOUNTING
3 from test -- and OPERATIONS have same length
4 where length(dname) = (select max(length(dname))
5 from test
6 )
7 );
4 rows updated.
SQL> select * from test;
DEPTNO DNAME LOC
---------- -------------- -------------
10 OPERATIONS NEW YORK
20 OPERATIONS DALLAS
30 OPERATIONS CHICAGO
40 OPERATIONS BOSTON
SQL>
[EDIT, GROUP BY]
Another example is based on a different table, which reflects what you described in a comment. The DEPTNO (department number) is used to "group" employees, and I'm going to update the JOB column value to the longest job name within that department.
Query is similar to the previous one; it just joins appropriate columns (DEPTNO) throughout code.
Sample data:
SQL> select * from test order by deptno, ename;
DEPTNO ENAME JOB
---------- ---------- ---------
10 CLARK MANAGER
KING PRESIDENT --> the longest in DEPTNO = 10
MILLER CLERK
20 ADAMS CLERK
FORD ANALYST
JONES MANAGER --> as long as ANALYST, but MAX(JOB) will return this value
SCOTT ANALYST
SMITH CLERK
30 ALLEN SALESMAN --> the longest in DEPTNO = 30
BLAKE MANAGER
JAMES CLERK
MARTIN SALESMAN
TURNER SALESMAN
WARD SALESMAN
Update and the result:
SQL> update test t set
2 t.job = (select max(t1.job)
3 from test t1
4 where t1.deptno = t.deptno
5 and length(t1.job) = (select max(length(t2.job))
6 from test t2
7 where t2.deptno = t1.deptno
8 )
9 );
14 rows updated.
SQL> select * from test order by deptno, ename;
DEPTNO ENAME JOB
---------- ---------- ---------
10 CLARK PRESIDENT
KING PRESIDENT
MILLER PRESIDENT
20 ADAMS MANAGER
FORD MANAGER
JONES MANAGER
SCOTT MANAGER
SMITH MANAGER
30 ALLEN SALESMAN
BLAKE SALESMAN
JAMES SALESMAN
MARTIN SALESMAN
TURNER SALESMAN
WARD SALESMAN