How to create stored procedure that returns query result?
-
19-01-2021 - |
Question
I have query that has a lot of columns (about 30) and I would like to place that query in stored procedure. The reason behind that is because this query is used in multiple places in the system. There are situations when I need to pull whole table result set and sometimes I need to look for specific record only (filtered by id). Here is example of the query:
SELECT
TRIM(t1.rec_id) AS rec_id,
TRIM(t1.date) AS date,
TRIM(t1.name) AS name,
TRIM(t1.address) AS address,
TRIM(t2.year) AS year,
CASE
WHEN LENGTH(TRIM(t3.percent)) <> 0 THEN CONCAT( ROUND( TRIM(t3.percent) * 100, 2) ,'% Whole' )
WHEN LENGTH(TRIM(t3.partial)) <> 0 THEN CONCAT( ROUND( TRIM(t3.partial) * 100, 2) ,'% Partial' )
END AS percent
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON TRIM(t1.rec_id) = TRIM(t2.rec_id)
LEFT OUTER JOIN table3 t3
ON TRIM(t1.rec_id) = TRIM(t3.rec_id)
-- Here I would like to add WHERE clause filter
-- If RecID argument is not NULL and is valid then query should filter
-- and return only one record. If not return all records.
ORDER BY t1.rec_id
Query above usually returns around 500-600
records. It's the main source of my application. In some situations I need all records and sometimes only specific record. So in my comment inside of the code above I explained the situation. The stored procedure should have one argument RecID
. If that argument is NULL
then stored procedure should return all records and columns. If ti's not NULL
then it should look for specific RecID
and return that row with all columns. I have done some work in SQL 2008+ where I used stored procedures. I'm wondering if someone can show me an example on how this would work in Oracle? I use Oracle 11g with ColdFusion 10. If someone have good example on how this can be completed please let me know. Thank you!
Solution
As of a view I suggested in a comment: as you already have a SELECT
statement, it is a matter of a few letters to convert it to a view. Here's an example:
SQL> select d.deptno, d.dname, e.empno, e.ename, e.job, e.sal
2 from dept d join emp e on e.deptno = d.deptno;
DEPTNO DNAME EMPNO ENAME JOB SAL
---------- -------------- ---------- ---------- --------- ----------
10 ACCOUNTING 7839 KING PRESIDENT 5000
10 ACCOUNTING 7782 CLARK MANAGER 2450
10 ACCOUNTING 7934 MILLER CLERK 1300
20 RESEARCH 7902 FORD ANALYST 3000
20 RESEARCH 7369 SMITH CLERK 800
20 RESEARCH 7566 JONES MANAGER 2975
30 SALES 7900 JAMES CLERK 950
30 SALES 7844 TURNER SALESMAN 1500
30 SALES 7654 MARTIN SALESMAN 1250
30 SALES 7521 WARD SALESMAN 1250
30 SALES 7499 ALLEN SALESMAN 1600
30 SALES 7698 BLAKE MANAGER 2850
12 rows selected.
SQL>
Convert it to a view:
SQL> create or replace view v_emps as
2 select d.deptno, d.dname, e.empno, e.ename, e.job, e.sal
3 from dept d join emp e on e.deptno = d.deptno;
View created.
SQL>
See? Lines 2 and 3 are what you already have.
Now, when you want to select something, you'd use a view instead of the same SELECT
statement over and over again. For example:
SQL> select dname, sum(sal) from v_emps group by dname;
DNAME SUM(SAL)
-------------- ----------
ACCOUNTING 8750
RESEARCH 6775
SALES 9400
SQL> select job, count(*) from v_emps group by job;
JOB COUNT(*)
--------- ----------
CLERK 3
SALESMAN 4
PRESIDENT 1
MANAGER 3
ANALYST 1
SQL> select ename from v_emps where deptno = 20;
ENAME
----------
SMITH
JONES
FORD
SQL>
Quite simple, isn't it?
A view is nothing but a stored query - it doesn't occupy any space, it always returns current data. True - if it is complex and deals with A LOT of data, it may be slow; but then performance tuning takes place.
I'd suggest you to try it; won't cost much, as you've seen - just a simple create or replace view v_emps
...