ROW_NUMBER function is nondeterministic
Can we categorize ROW_NUMBER function as nondeterministic. I think, unless we provide column names in the ORDER BY clause to uniquely identify a raw.
" windowed functions are non-deterministic either way you look at them ;)"
This is not true. Some Window Functions are deterministic others are not. The OP wanted to know if ROW_NUMBER was was non-deterministic; and yes, ROW_NUMBER is non-deterministic.
There are four functions in T-SQL that are referred to as "ranking functions": ROW_NUMBER, NTILE, RANK and DENSE_RANK. RANK and DENSE_RANK are deterministic, ROW_NUMBER and NTILE are not. To better understand this please note the queries below
(you can copy/paste into ssms):
DECLARE @names TABLE (name_txt varchar(100) not null, phone_nbr varchar(20) not null);
WITH rand_names AS
SELECT TOP 10 *
FROM (VALUES
('bob', '555-1212'),('bob', '555-1245'),('bob', '555-7896'),
('al', '555-8888'),('zach', '555-9999')
) t(n,p)
ORDER BY newid()
INSERT @names
SELECT * FROM rand_names;
-- query1
SELECT [ROW_NUMBER()] = ROW_NUMBER() over (order by name_txt),
[NTILE(2)] = NTILE(2) over (order by name_txt),
[RANK()] = RANK() over (order by name_txt),
[DENSE_RANK()] = DENSE_RANK() over (order by name_txt), *
FROM @names;
-- query2
SELECT [ROW_NUMBER()] = ROW_NUMBER() over (order by (select null)),
[NTILE(2)] = NTILE(2) over (order by (select null)),
[RANK()] = RANK() over (order by (select null)),
[DENSE_RANK()] = DENSE_RANK() over (order by (select null)), *
FROM @names;
Similar Messages
-
Use of ROW_NUMBER() function in PL/SQL
I have a Table Emp with the following Structure
SQL> desc emp
Name Null? Type
EMPNO NUMBER(2)
ENAME VARCHAR2(50)
HIREDATE DATE
DEPTNO NUMBER(2)
If I write a following query on this table
SQL> SELECT deptno, hiredate, record_id
2 FROM (SELECT deptno, ename, hiredate, ROW_NUMBER()
3 OVER (ORDER BY hiredate) AS record_id
4 FROM emp)
5 WHERE record_id >= 2
6 AND record_id <=5;
The Result I get is
DEPTNO HIREDATE RECORD_ID
10 22-NOV-01 2
10 22-NOV-01 3
10 22-NOV-01 4
10 22-NOV-01 5
But if I put this query in a cursor in a PL/SQL block. The
pl/sql does not compiles and gives me the following address
SQL> DECLARE
2 CURSOR c_my IS
3 SELECT deptno, hiredate, record_id
4 FROM (SELECT deptno, ename, hiredate, ROW_NUMBER()
5 OVER (ORDER BY hiredate) AS record_id
6 FROM emp)
7 WHERE record_id >= 2
8 AND record_id <=5;
9 BEGIN
10 FOR c_rec IN c_my LOOP
11 dbms_output.put_line(c_rec.ename);
12 END LOOP;
13 END;
14 /
OVER (ORDER BY hiredate) AS record_id
ERROR at line 5:
ORA-06550: line 5, column 13:
PLS-00103: Encountered the symbol "(" when expecting one of the
following:
, from
Question: Can you please tell me how I can use the ROW_NUMBER()
function in PL/SQL. I need to use this for selecting the correct
range of records for Pagination on a website.
Thanks in advance
PrashantAs Andrew said, PL/SQL hasn't caught up with the newer bits of
SQL. I have heard that in 9i, they will be the same, but in 8i
there are still things that you can do in SQL that you cannot do
directly in PL/SQL, such as the new functions like ROW_NUMBER.
However, you can use NDS as a work around. The following does
the same as what you posted:
SET SERVEROUTPUT ON
DECLARE
TYPE c_my_type IS REF CURSOR;
c_my c_my_type;
TYPE c_rec_type IS RECORD
(deptno emp.deptno%TYPE,
ename emp.ename%TYPE,
hiredate emp.hiredate%TYPE,
record_id INTEGER);
c_rec c_rec_type;
v_sql VARCHAR2 (4000);
BEGIN
v_sql :=
'SELECT deptno, ename, hiredate, record_id
FROM (SELECT deptno, ename, hiredate,
ROW_NUMBER() OVER
(ORDER BY hiredate)
AS record_id
FROM emp)
WHERE record_id >= 2
AND record_id <= 5';
OPEN c_my FOR v_sql;
LOOP
FETCH c_my INTO c_rec;
EXIT WHEN c_my%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (c_rec.ename);
END LOOP;
END;
However, you stated that you need it for selecting the correct
range of records for pagination on a website. For that, you
will want something more like this:
CREATE OR REPLACE PACKAGE package_name
AS
TYPE c_my_type IS REF cursor;
PROCEDURE procedure_name
(c_my IN OUT c_my_type,
p_record_id1 IN NUMBER DEFAULT 1,
p_record_id2 IN NUMBER DEFAULT 4);
END package_name;
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE procedure_name
(c_my IN OUT c_my_type,
p_record_id1 IN NUMBER DEFAULT 1,
p_record_id2 IN NUMBER DEFAULT 4)
IS
v_sql VARCHAR2 (4000);
BEGIN
v_sql :=
'SELECT deptno, ename, hiredate, record_id'
|| ' FROM (SELECT deptno, ename, hiredate,'
|| ' ROW_NUMBER() OVER'
|| ' (ORDER BY hiredate)'
|| ' AS record_id'
|| ' FROM emp)'
|| ' WHERE record_id >= :a'
|| ' AND record_id <= :b';
OPEN c_my FOR v_sql
USING p_record_id1, p_record_id2;
END procedure_name;
END package_name; -
Row_number function not starting from 1
I have two row_number functions in my select statement both has same columns and condition for partition and order by,
except one column in order by which is being ordered by DESC.below is function :
row_number() over (partition by event_cd order by status ASC ,event_date DESC) row1
row_number() over (partition by event_cd order by status DESC ,event_date DESC) row2
Status field has value 0 for incompleted and 1 for completed,if its 0 there will be no date.
The original set of data is :
event_cd status event_date
tsk 0
tsk 0
tsk 1 25-aug-2006
tsk 1 28-aug-2006
tsk 1 31-aug-2006
tsk 1 01-sep-2006
Result I am getting for row1 is
status row1
0 1
0 2
1 3
1 4
1 5
1 6
Result for row2 is
status row1
1 5
1 6
1 1
1 2
0 3
0 4
My confusion is why row2 has not its row number starting from 1,it looks like its
depending on row1 results?If yes,then why?Looks fine to me:
SQL> create table mytable
2 as
3 select 'tsk' event_cd, 0 status, null event_date from dual union all
4 select 'tsk', 0, null from dual union all
5 select 'tsk', 1, date '2006-08-25' from dual union all
6 select 'tsk', 1, date '2006-08-28' from dual union all
7 select 'tsk', 1, date '2006-08-31' from dual union all
8 select 'tsk', 1, date '2006-09-01' from dual
9 /
Tabel is aangemaakt.
SQL> select t.*
2 , row_number() over (partition by event_cd order by status ASC ,event_date DESC) row1
3 , row_number() over (partition by event_cd order by status DESC ,event_date DESC) row2
4 from mytable t
5 /
EVE STATUS EVENT_DATE ROW1 ROW2
tsk 0 1 5
tsk 0 2 6
tsk 1 01-09-2006 00:00:00 3 1
tsk 1 31-08-2006 00:00:00 4 2
tsk 1 28-08-2006 00:00:00 5 3
tsk 1 25-08-2006 00:00:00 6 4
6 rijen zijn geselecteerd.Regards,
Rob. -
Problems with Row_Number function
I am having problems with the Row_Number function. I am using it to assign row numbers to records where a student has a grade of pass on a module and excluding failed modules (I want it to show a 0 as row number for failed modules). The problem is that when I try to use a condition, the report still assigns a row number to a failed module though it doesnt display it (it displays a 0 which I wanted it to show). The results appear as follows:
Row number
Module
Grade
1
ModuleA
Pass
2
ModuleB
Pass
0
ModuleC
Fail
4 (instead of 3)
ModuleD
Pass
How can I make it skip assigning a row number to all failed modules? Please assist.
Thanks.It is tricky to use rownum. Because if we generate sequence no by select max(column)+1 from table name ..we can match the where condition and assign the incremented value to the PASS condition.
On the other hand rownum generates a sequence while it is fetching the records one by one so obviously you get the above result only So i will give you an idea to fetch the records of 'PASS' condition first.
Take a look at the below query and alter it and use it on your report.
select a,b,c from (
select 0 a,module b, grade c from table where grade = 'FAIL'
union all
select rownum a,module b, grade c from table where grade = 'PASS' order by b)
order by a
So the above query generates row number only for the PASS condition.
Hope this helps...
Regards,
Soofi. -
Is that important column order in a query with row_number function
Hi folks,
I am using Oracle 11g R2 on HP-UX machine.
I have 2 types of query with row_number and I think they are same but output of each of them are different. I changed only column order in query2.
Query 1 :
(SELECT
"LOOKUP_INPUT_SUBQUERY"."CONTRACT_SK" "CONTRACT_SK",
"LOOKUP_INPUT_SUBQUERY"."SIMCARD_SK" "SIMCARD_SK"
FROM (
SELECT row_number ()
OVER (
PARTITION BY "R_CON_SUBS_SIMCARD_LK".
"CONTRACT_SK"
ORDER BY
"R_CON_SUBS_SIMCARD_LK"."START_DATE" DESC,
"R_CON_SUBS_SIMCARD_LK"."SEQ_NUM" DESC NULLS LAST) /* EXPRESSION_3.OUTGRP1.SIRA */
"SIRA",
"R_CON_SUBS_SIMCARD_LK"."CONTRACT_SK" "CONTRACT_SK",
"R_CON_SUBS_SIMCARD_LK"."SIMCARD_SK" "SIMCARD_SK"
FROM "SRC_OZRDS"."R_CON_SUBS_SIMCARD_LK" "R_CON_SUBS_SIMCARD_LK")
"LOOKUP_INPUT_SUBQUERY"
WHERE ("LOOKUP_INPUT_SUBQUERY"."SIRA" = 1))
Output of this like that :
CONTRACT_SK SIMCARD_SK
1 1
1 3
1 4
1 5
1 6
1 11
1 12
1 14
1 15
1 16
Query 2 :
(SELECT
"LOOKUP_INPUT_SUBQUERY"."CONTRACT_SK" "CONTRACT_SK",
"LOOKUP_INPUT_SUBQUERY"."SIMCARD_SK" "SIMCARD_SK"
FROM (
SELECT
"R_CON_SUBS_SIMCARD_LK"."CONTRACT_SK" "CONTRACT_SK",
"R_CON_SUBS_SIMCARD_LK"."SIMCARD_SK" "SIMCARD_SK",
row_number ()
OVER (
PARTITION BY "R_CON_SUBS_SIMCARD_LK".
"CONTRACT_SK"
ORDER BY
"R_CON_SUBS_SIMCARD_LK"."START_DATE" DESC,
"R_CON_SUBS_SIMCARD_LK"."SEQ_NUM" DESC NULLS LAST) /* EXPRESSION_3.OUTGRP1.SIRA */
"SIRA"
FROM "SRC_OZRDS"."R_CON_SUBS_SIMCARD_LK" "R_CON_SUBS_SIMCARD_LK")
"LOOKUP_INPUT_SUBQUERY"
WHERE ("LOOKUP_INPUT_SUBQUERY"."SIRA" = 1))
Output of this like that:
2 874812
7 70097256
8 18734091
9 158024
10 815397739
13 22657919
19 83177779
20 82579529
22 5829949
23 35348926
25 3865978
I expected the second output, because there are lots of contract sk but there is one contract_sk in first query result. i did not get the point. What is the problem ?user8649469 wrote:
I changed only column order in query2.So what else do you expect? If you order, for example, by last name, fist name don't you think rows will be returned in a different order (and therefore same row will have different row number) than ordering by first name, last name?
SY. -
Hello every one, can I rewrite the following query without using the 'ROW_NUMBER() OVER ' part.
The query is supposed to pull out the records whose CODE is not NULL and has most
recent date for UPDATE_DATE . The reason I wanted to do this is, When I embed this query
in between many other queries along with JOINs, My oracle server is unable to execute. So, I thought
its better to supplant 'ROW_NUMBER() OVER ' logic with something else and try it. .
SELECT a.* FROM
(SELECT b.*, ROW_NUMBER() OVER (PARTITION BY b.PIDM
ORDER BY b.UPDATE_DATE DESC) AS Rno
FROM
SELECT *
FROM SHYNCRO WHERE CODE IS NOT NULL
)b
)a
WHERE a.Rno = 1Hi,
You didn't write over 150 lines of code and then start testing it, did you?
Don't.
Take baby steps. Write as little as pssiblem test that. Debug and test again until you have something that does exactly what you want it to do.
When you have somehting that works perfectly, take one baby step. Add a tiny amount of code, maybe 1 or 2 lines more, and test again.
When you do get an error, or wrong results, you'll have a much better idea of where the problem is. also, you won't be building code on a flimsy foundation.
If you need help, post the last working version and the new version with the error. Explain what you're trying to do in the new version.
The error message indicates line 133. It looks like line 133 of your code is blank. Does your front end allow completely blank lines in the middle of a query? SQL*Plus doesn't by default; you have to say
SET SQLBLANKLINES ONto have a completely blank line in SQL*Plus. (However, lines containing nothing but at commnet are always allowed.)
You may have noticed that this site normally doesn't display multiple spaces in a row.
Whenever you post formatted text (such as indented code) on this site, type these 6 characters:
\(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing.
The 4 people who posted small code fragments for you to read all did this. It would be so much easier for people to read your humongeous query if it were formatted. -
Generating sequence Using row_number function.
Hello All,
I want to know if we can create sequence using row_number .
I know we can create sequence using row_number but I want to start my sequence from 001, can we create using row_number?
It will be great, If I can get a faster response.
Thanks in advance.user13034857 wrote:
Hello All,
I want to know if we can create sequence using row_number .
I know we can create sequence using row_number but I want to start my sequence from 001, can we create using row_number?
It will be great, If I can get a faster response.
Thanks in advance.
SQL> set pagesize 60
SQL> SELECT TO_CHAR (ROWNUM, '000') Seq, s.table_name
2 FROM user_tables s
3 WHERE ROWNUM <= 20;
SEQ TABLE_NAME
001 ICOL$
002 CON$
003 UNDO$
004 PROXY_ROLE_DATA$
005 FILE$
006 UET$
007 IND$
008 SEG$
009 COL$
010 CLU$
011 PROXY_DATA$
012 TS$
013 BOOTSTRAP$
014 FET$
015 CCOL$
016 USER$
017 OBJ$
018 TAB$
019 CDEF$
020 OBJERROR$
20 rows selected.
SQL>
SQL> SELECT TO_CHAR (ROW_NUMBER () OVER ( ORDER BY dept),
2 '000')
3 Seq,
4 empno,
5 ename,
6 dept
7 FROM Emp;
SEQ EMPNO ENAME DEPT
001 2345 zxcv 10
002 1111 qwer 10
003 1234 asdf 20
004 5657 ghjk 20
005 3125 tyui 30
006 2134 zxvnb 30
007 8907 cvmn 30
7 rows selected.
SQL>
SQL> -
WITHOUT USING ROW_NUMBER FUNCTIONS IN T-SQL
INPUT:-
CUST_ID
GIFT_ID
100
10
100
20
100
30
200
10
200
20
200
30
300
20
OUTPUT:-
CUST_ID
GIFT_ID
SEQ
100
10
1
100
20
2
100
30
3
200
10
1
200
20
2
200
30
3
300
20
1
santoshbangaloreTHANK YOU SO MUCH FOR YOUR ANS? BUT MY INPUT TABLE A CONTAIN ONLY TWO COLUMN'S
CUST_ID,GIFT_ID
AND IN OUT PUT I NEED THE ABOVE OUTPUT WITH
CUST_ID,GIFT_ID,ROW_NUMBER AS SHOWN ABOVE?
santoshbangalore -
Row_number() function error in forms 10g
I used sentence below in forms 10g then an error occured.
row_number() over(partition by GROUP_L1 order by GROUP_L1, GROUP_L2) RN
error : Encountered the symbol "(" when expecting one of the following : , from
above sentence works well in the Toad (<= oracle client tool).
How can you solve this problem?
Edited by: user13763783 on 2011. 3. 8 오후 5:26Yes Ahmed's Point of View is Correct
you can write a stored procedure on the database and then return the result to Forms. Forms can then call this Stored Procedure.
Alternatively , i believe it's much more easy approach to define a view
view operates just like a table So you can reference this view in any Trigger or any Program Unit.
Hope this helps...
Regards,
Abdetu... -
Not right data when row_number used in inner-view sql query...
Hi ,
I use the below sql statement which displays the right data
select CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE , SUM_POSOTITA , row_number() over(partition by code_farmakou order by sum_posotita desc) from
(SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES ,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_CLINIC A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_EX_IATR A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_FOREON_MS A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_GEN_SINT_KLIN A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_GEN_SINT_EX_IATR A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS)The data are:
CODE_FARMAKOU EMP_NAME PACKTYPE PACKSIZE SUM_POSOTITA ROW_NUMBER()OVER(PARTITIONBYCO
0000002419 FACTREL INJECTION VIAL 2 ML 5 1
0000014071 DOPAMINE HYDROCHLORIDE VIAL 5 ML X 25 30 1
0000086289 DETUSSIN EXPECTORANT BOT 120 ML 3 1
1000000760 DEPON BT 20(BLIST2X10) 2 1
1000000760 DEPON BT 20(BLIST2X10) 1 2
1000003279 MOXACEF BT 40(BLIST10X4) 45 1
1000003279 MOXACEF BT 40(BLIST10X4) 1 2
1000003279 MOXACEF BT 40(BLIST10X4) 1 3
1000014127 DEPON VIT. C BT 2TUBX10 6 1
1000014127 DEPON VIT. C BT 2TUBX10 2 2
1000016655 KABIVEN BT 50ÖÕÓ.×1,7ML 21 1
1000016655 KABIVEN BT 50ÖÕÓ.×1,7ML 2 2However , when i use the below statement , in order not to display the row_number (so i use row_number function in inner-view) the data are different--in different order... why is that????
select CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE , SUM_POSOTITA from
select CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE , SUM_POSOTITA , row_number() over(partition by code_farmakou order by sum_posotita desc) from
(SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES ,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_CLINIC A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_EX_IATR A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_AT_SINT_FOREON_MS A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_GEN_SINT_KLIN A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS
UNION ALL
SELECT CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, TO_DATE(DATES_EKTELESIS,'DD/MM/RRRR') DATES,SUM(POSOTITA) SUM_POSOTITA
FROM EKTELESI_GEN_SINT_EX_IATR A, MITROO_FARMAKOU B
WHERE CODE_FARMAKOU = FARMAK_CODE
GROUP BY CODE_FARMAKOU,EMP_NAME,PACKTYPE,PACKSIZE, DATES_EKTELESIS)
)and its data are:
CODE_FARMAKOU EMP_NAME PACKTYPE PACKSIZE SUM_POSOTITA
1000016655 KABIVEN BT 50ΦΥΣ.Χ1,7ML 21
1000016655 KABIVEN BT 50ΦΥΣ.Χ1,7ML 2
1000000760 DEPON BT 20(BLIST2X10) 2
1000014127 DEPON VIT. C BT 2TUBX10 2
1000003279 MOXACEF BT 40(BLIST10X4) 45
0000014071 DOPAMINE HYDROCHLORIDE VIAL 5 ML X 25 30
0000086289 DETUSSIN EXPECTORANT BOT 120 ML 3
1000014127 DEPON VIT. C BT 2TUBX10 6
1000003279 MOXACEF BT 40(BLIST10X4) 1
1000003279 MOXACEF BT 40(BLIST10X4) 1
0000002419 FACTREL INJECTION VIAL 2 ML 5
1000000760 DEPON BT 20(BLIST2X10) 1NOTE :Sorry, I tried to pose some sample data using the "with" statement but i couldn't...the error ORA-32035 : unreferenced query name defined in WITH clause was displayed..
Regards,
SimonThe optimizer has, well, optimized out the row_number because you never refer to its value in the outermost query.
sql>select deptno, cnt, row_number() over (order by cnt desc) rn
2 from (select deptno, count(*) cnt
3 from emp
4 group by deptno);
DEPTNO CNT RN
30 6 1
20 5 2
10 3 3
3 rows selected.
-- here because we include rn in the outermost query,
-- the results are still ordered based on the analytical function result
sql>select deptno, cnt, rn
2 from (select deptno, cnt, row_number() over (order by cnt desc) rn
3 from (select deptno, count(*) cnt
4 from emp
5 group by deptno));
DEPTNO CNT RN
30 6 1
20 5 2
10 3 3
3 rows selected.
-- but if we don't include rn in the outermost query,
-- the optimizer leaves out the window sort and the results are in a different order
sql>select deptno, cnt
2 from (select deptno, cnt, row_number() over (order by cnt desc) rn
3 from (select deptno, count(*) cnt
4 from emp
5 group by deptno));
DEPTNO CNT
10 3
20 5
30 6
3 rows selected.This just reinforces the point that if you want your results in a particular order, you need to provide an ORDER BY clause - don't rely on execution plans to do your sorting for you. -
Return multiple values from a function to a SELECT statement
I hope I've provided enough information here. If not, just let me know what I'm missing.
I am creating a view that will combine information from a few tables. Most of it is fairly straightforward, but there are a couple of columns in the view that I need to get by running a function within a package. Even this is fairly straightforward (I have a function named action_date in a package called rp, for instance, which I can use to return the date I need via SELECT rp.action_date(sequence_number).
Here's the issue: I actually need to return several bits of information from the same record (not just action_date, but also action_office, action_value, etc.) - a join of the tables won't work here as I'll explain below. I can, of course, run a separate function for each statement but that is obviously inefficient. Within the confines of the view select statement however, I'm not sure how to return each of the values I need.
For instance, right now, I have:
Table1:
sequence_number NUMBER(10),
name VARCHAR(30),
Table2:
Table1_seq NUMBER(10),
action_seq NUMBER(10),
action_date DATE,
action_office VARCHAR(3),
action_value VARCHAR(60),
I can't simply join Table1 and Table2 because I have to do some processing in order to determine which of the matching returned rows I actually need to select. So the package opens a cursor and processes each row until it finds the one that I need.
The following works but is inefficient since all of the calls to the package will return columns from the same record. I just don't know how to return all the values I need into the SELECT statement.
CREATE VIEW all_this_stuff AS
SELECT sequence_number, name,
rp.action_date(sequence_number) action_date,
rp.action_office(sequence_number) action_office,
rp.action_value(sequence_number) action_value
FROM table1
Is there a way to return multiple values into my SELECT statement or am I going about this all wrong?
Any suggestions?
Thanks so much!Hi,
What you want is a Top-N Query , which you can do using the analytic ROW_NUMBER function in a sub-query, like this:
WITH got_rnum AS
SELECT action_seq, action_dt, action_office, action_type, action_value
, ROW_NUMBER () OVER ( ORDER BY action_date
, action_seq
, action_serial
) AS rnum
FROM table2
WHERE action_code = 'AB'
AND action_office LIKE 'E' -- Is this right?
SELECT action_seq, action_dt, action_office, action_type, action_value
FROM got_rnum
WHERE rnum = 1
;As written, this will return (at most) one row.
I suspect you'll really want to get one row for each group , where a group is defined by some value in a table to which you're joining.
In that case, add a PARTITION BY clause to the ROW_NUMBER function.
If you'd post a little sample data (CREATE TABLE and INSERT statements), I could show you exactly how.
Since I don't have your tables, I'll show you using tables in the scott schema.
Here's a view that has data from the scott.dept table and also from scott.emp, but only for the most senior employee in each department (that is, the employee with the earliest hiredate). If there happens to be a tie for the earliest hiredate, then the contender with the lowest empno is chosen.
CREATE OR REPLACE VIEW senior_emp
AS
WITH got_rnum AS
SELECT d.deptno
, d.dname
, e.empno
, e.ename
, e.hiredate
, ROW_NUMBER () OVER ( PARTITION BY d.deptno
ORDER BY e.hiredate
, e.empno
) AS rnum
FROM scott.dept d
JOIN scott.emp e ON d.deptno = e.deptno
SELECT deptno
, dname
, empno
, ename
, hiredate
FROM got_rnum
WHERE rnum = 1
SELECT *
FROM senior_emp
;Output:
. DEPTNO DNAME EMPNO ENAME HIREDATE
10 ACCOUNTING 7782 CLARK 09-JUN-81
20 RESEARCH 7369 SMITH 17-DEC-80
30 SALES 7499 ALLEN 20-FEB-81
By the way, one of the conditions in the query you posted was
action_office LIKE 'E'which is equivalent to
action_office = 'E'(LIKE is always equivalent to = if the string after LIKE doesn't contain any wildcards.)
Did you mean to say that, or did you mean something like this:
action_office LIKE 'E%'instead? -
[8i] Help with function with parameters (for workday calculation)
Let me start by saying, I've never written a function before, and I don't have access to create a function in my database (i.e. I can't test this function). I'm trying to come up with a function that I can ask my IT department to add for me. I'm hoping someone can take a look at what I've written and tell me if it should work or not, and if this is the right way to go about solving my problem.
I am trying to create a function to do a very simple workday calculation (adding/subtracting a particular number of workdays from a calendar date).
The database I'm working with has a table with the workday calendar in it. Here is a sample table and sample data, representative of what's in my workday calendar table:
CREATE TABLE caln
( clndr_dt DATE,
shop_days NUMBER(5)
CONSTRAINT caln_pk PRIMARY KEY (clndr_dt)
INSERT INTO caln
VALUES (To_Date('01/01/1980','mm/dd/yyyy'),0);
INSERT INTO caln
VALUES (To_Date('01/02/1980','mm/dd/yyyy'),1);
INSERT INTO caln
VALUES (To_Date('01/03/1980','mm/dd/yyyy'),2);
INSERT INTO caln
VALUES (To_Date('01/04/1980','mm/dd/yyyy'),3);
INSERT INTO caln
VALUES (To_Date('01/05/1980','mm/dd/yyyy'),3);
INSERT INTO caln
VALUES (To_Date('01/06/1980','mm/dd/yyyy'),3);
INSERT INTO caln
VALUES (To_Date('01/07/1980','mm/dd/yyyy'),4);
INSERT INTO caln
VALUES (To_Date('01/08/1980','mm/dd/yyyy'),5);
INSERT INTO caln
VALUES (To_Date('01/09/1980','mm/dd/yyyy'),6);
INSERT INTO caln
VALUES (To_Date('01/10/1980','mm/dd/yyyy'),7);
INSERT INTO caln
VALUES (To_Date('01/11/1980','mm/dd/yyyy'),8);
INSERT INTO caln
VALUES (To_Date('01/12/1980','mm/dd/yyyy'),8);
INSERT INTO caln
VALUES (To_Date('01/13/1980','mm/dd/yyyy'),8);
INSERT INTO caln
VALUES (To_Date('01/14/1980','mm/dd/yyyy'),9);The actual table includes from 1/1/1980 though 12/31/2015.
I've written (and validated) this parameter query which does my workday (mday) calculation:
SELECT cal.clndr_dt
FROM CALN cal
SELECT cal.shop_days+:mdays AS new_shop_days
FROM CALN cal
WHERE cal.clndr_dt =:start_date
) a
WHERE cal.shop_days = a.new_shop_days
AND ROWNUM =1
ORDER BY cal.clndr_dt;Based on this query, I've created the following function (and I have no clue if it works or if the syntax is right, etc.):
CREATE OR REPLACE FUNCTION add_mdays
(start_date IN DATE,
mdays IN NUMBER(5))
RETURN DATE
IS
new_date DATE;
BEGIN
SELECT cal.clndr_dt
FROM CALN cal
SELECT cal.shop_days+mdays AS new_shop_days
FROM CALN cal
WHERE cal.clndr_dt =start_date
) a
WHERE cal.shop_days = a.new_shop_days
AND ROWNUM =1
ORDER BY cal.clndr_dt;
RETURN new_date;
END add_mdays; //edit 9:31 AM - noticed I left off this bitI'm also not sure how to have the function handle results that would return a date outside of the date range that is in the table (Before 1/1/1980 or after 12/31/2015--or, another way to look at it is, before the MIN value of caln.clndr_dt or after the MAX value of caln.clndr_dt).
My goal is to be able to use the function in a situation like the following:
First, here's a sample table and data:
CREATE TABLE orders
( ord_no NUMBER(5),
plan_start_dt DATE,
CONSTRAINT orders_pk PRIMARY KEY (ord_no)
INSERT INTO orders
VALUES (1,To_Date('01/08/1980','mm/dd/yyyy'));
INSERT INTO orders
VALUES (2,To_Date('01/09/1980','mm/dd/yyyy'));
INSERT INTO orders
VALUES (3,To_Date('01/10/1980','mm/dd/yyyy'));And here is how I would like to use my function:
SELECT orders.ord_no
, orders.plan_start_dt
, add_mdays(orders.plan_start_dt, -3) AS prep_date
FROM ordersThus, the function would allow me to return, for every order in my orders table, the date that is 3 workdays (mdays) prior to the plan start date of each order.
Am I going about this the right way? Do I need to create a function to do this, or is there a way for me to incorporate my query (that does my mday calculation) into the sample query above (eliminating the need to create a function)?
Thanks much in advance!
Edited by: user11033437 on Feb 2, 2010 8:55 AM
Fixed a couple typos in the last insert statements
Edited by: user11033437 on Feb 2, 2010 9:31 AM (fixed some syntax in the function)Hi,
Ah, mentioning Oracle 8 and not being able to test your own code makes me nostalgic for the good old days, when you typed your cards, and brought them to a window at the computer center, and waited an hour for the job to run, and then saw the printout to find that you had made a typo.
If you're going to write functions, you really need to test them yourself. Like all code, functions whould be written in baby steps: write a line or two (or sometimes just part of what will later become one line), test, make sure it's running correctly, and repeat.
Ideally, your employer should create a developement schema in a development database for you to use.
You can legally download your own instance of Oracle Express Edition for free; just be careful not to use features that aren't available in the database where the code will be deployed.
You don't need a function to get the results you want:
SELECT o.ord_no
, o.plan_start_dt
, MIN (e.clndr_dt) AS prep_date
FROM orders o
, caln l
, caln e
WHERE l.clndr_dt = o.plan_start_dt
AND e.shop_days = l.shop_days - 3
GROUP BY o.ord_no
, o.plan_start_dt
;This would be more efficient (and a little simpler) if you added a column (let's call it work_day) that identified if each row represented a work_day or not.
For each value of shop_days, exactly 1 row will be marked as a work day.
Then the query might be something like:
SELECT o.ord_no
, o.plan_start_dt
, e.clndr_dt AS prep_date
FROM orders o
, caln l
, caln e
WHERE l.clndr_dt = o.plan_start_dt
AND e.shop_days = l.shop_days - 3
AND e.work_day = 1
;You could use the analytic LAG function to populate the work_day column.
A function would certainly be handy, though perhaps slower.
The function you posted has a few mistakes:
(a) An argument can't be declared as NUMBER (5); just NUMBER.
(b) When you SELECT in PL/SQL, like you're doing, you have to SELECT INTO some variable to hold the results.
(c) ROWNUM is arbitrary (which makes it useless in this problem) unless you are drawing from an ordered sub-query. I don't think you can use ORDER BY in sub-queries in Oracle 8. Use the analytic ROW_NUMBER function instead.
(d) The function must end with an END statement.
Given your current caln table, here's how I would write the function:
CREATE OR REPLACE FUNCTION add_mdays
( start_date IN DATE DEFAULT SYSDATE,
mdays IN NUMBER DEFAULT 1
RETURN DATE
DETERMINISTIC
IS
-- add_mdays returns the DATE that is mdays working days
-- after start_date. (If mdays < 0, the DATE returned
-- will be before start_date).
-- Work days do not include Saturdays, Sundays or holidays
-- as indicated in the caln table.
new_date DATE; -- to be returned
BEGIN
SELECT MIN (t.clndr_dt)
INTO new_date
FROM caln f -- f stands for "from"
, caln t -- t stands for "to"
WHERE f.clndr_dt = TRUNC (start_date)
AND t.shop_days = f.shop_days + TRUNC (mdays)
RETURN new_date;
END add_mdays;
SHOW ERRORSProduction code whould be robust (that includes "idiot-proofing").
Try to foresee what errors people might make in calling your function, and correct for them when possible.
For example, if it only makes sense for start_date to be midnight, or mdays to be an integer, then use TRUNC in the function in case soembody passes a bad value.
Allow for default arguments.
Comment your function. Put all comments within the function (that is, after CREATE and before the final END) so that they will be kept in the data dictionary.
If, given the same arguments, the function always returns the same value, mark it as DETERMINISTIC, for efficiency. This means the system may remember values passed back rather than call the function every time it is told to.
I wish I could mark questions as "Correct" or "Helpful"; you'd get 10 points for sure.
You posted CREATE TABLE and INSERT statements (without even being begged).
You gave a clear description of the problem, including desired results.
The code is nicely formatted and easy to read.
All around, one of the most thoughtful, well-written questions I've seen.
Well done! Keep up the good work!
Edited by: Frank Kulash on Feb 2, 2010 1:10 PM
Added my own version of the function. -
Help needed with analytical function
I want to get the employee details of the highest and 2nd highest salaried employee in a particular department. But also the department should have more than 1 employee.
I tried the query and it gave me proper results. But I'm wondering if there is some other alternative than using the subquery.
Here is the table and the result query :
with t as
select 1 emp_id,3 mgr_id,'Rajesh' emp_name,3999 salary,677 bonus,'HR' dpt_nme from dual union
select 2 ,3 ,'Gangz',4500,800,'Finance' from dual union
select 3 ,4 ,'Sid',8000,12000,'IT' from dual union
select 4 ,null,'Ram',5000,677,'HR' from dual union
select 5 ,4,'Shyam',6000,677,'IT' from dual union
select 6 ,4 ,'Ravi',9000,12000,'IT' from dual
select * from
(select emp_id, mgr_id, emp_name, dpt_nme, salary, row_number() over (partition by dpt_nme order by salary desc) rn from t where dpt_nme in
(select dpt_nme from t group by dpt_nme having count(*) > 1)) where rn < 3Hi,
You need a sub-query, but you don't need more than that.
Here's one way to eliminate the extra sub-query:
WITH got_analytics AS
SELECT emp_id, mgr_id, emp_name, dpt_nme, salary
, ROW_NUMBER () OVER ( PARTITION BY dpt_nme
ORDER BY salary DESC
) AS rn
, COUNT (*) OVER ( PARTITION BY dpt_nme
) AS dpt_cnt
FROM t
SELECT emp_id, mgr_id, emp_name, dpt_nme, salary
, rn
FROM got_analytics
WHERE rn < 3
AND dpt_cnt > 1
;Analytic functions are computed after the WHERE clause is applied. Since we need to use the results of the analytic ROW_NUMBER function in a WHERE clause, that means we'll have to compute ROW_NUMBER in a sub-query, and use the results in the WHERE clause of the main query. We can call the analytic COUNT function in the same sub-query, and use its results in the same WHERE clause of the main query.
What results would you want if there's a tie for the 2nd highest salary in some department? For example, if you add this row to your sample data:
select 7 ,3 ,'Sunil',8000,12000,'IT' from dual union? You may want to use RANK instead of ROW_NUMBER. -
MAX Function not returning MAX
I have a query that is pulling in EDI 214 status codes, and want to pull in the last received status for status type "AG". To do this, I'm using the MAX function on the INSERT_DATE field of the status code AG, but the query keeps returning both AG status codes. I've tried this in a single query (Query 1) but it did not work so I also attempted it in a much smaller query to be used as a subquery, but that still did not work. Can anyone identify what the issue is with what I'm attempting to do?
Query 1 (All Inclusive):
SELECT BS.SHIPMENT_GID AS BUY_SHIPMENT_GID,
AGSS.EVENTDATE AS AG_EVENT,
D1SS.EVENTDATE AS D1_EVENT,
BS.START_TIME AS BUY_START_TIME,
AGSS.STATUS_CODE_GID AS AG,
D1SS.STATUS_CODE_GID AS D1,
BS.DOMAIN_NAME AS BUY_DOMAIN,
MAX(AGSS.INSERT_DATE) AS AG_INSERT_DATE,
MAX(D1SS.INSERT_DATE) AS D1_INSERT_DATE,
BS.START_TIME,
BS.DOMAIN_NAME,
SHIPSTAT.STATUS_VALUE_GID
FROM V_ROD_SHIPMENT BS
INNER JOIN V_ROD_SS_STATUS_HISTORY AGSH
ON (BS.SHIPMENT_GID = AGSH.SHIPMENT_GID)
INNER JOIN V_ROD_IE_SHIPMENTSTATUS AGSS
ON (AGSH.I_TRANSACTION_NO = AGSS.I_TRANSACTION_NO)
INNER JOIN V_ROD_SS_STATUS_HISTORY D1SH
ON (BS.SHIPMENT_GID = D1SH.SHIPMENT_GID)
INNER JOIN V_ROD_SHIPMENT_STATUS SHIPSTAT
ON (BS.SHIPMENT_GID = SHIPSTAT.SHIPMENT_GID)
INNER JOIN V_ROD_IE_SHIPMENTSTATUS D1SS
ON D1SH.I_TRANSACTION_NO = D1SS.I_TRANSACTION_NO
WHERE BS.START_TIME > '18/MAY/12'
AND BS.DOMAIN_NAME = 'UPS/CP/HDMB'
AND AGSS.STATUS_CODE_GID = 'AG'
AND D1SS.STATUS_CODE_GID = 'D1'
AND (SHIPSTAT.STATUS_VALUE_GID = BS.DOMAIN_NAME
|| '.SECURE RESOURCES_ACCEPTED'
OR SHIPSTAT.STATUS_VALUE_GID = BS.DOMAIN_NAME
|| '.SECURE RESOURCES_PICKUP NOTIFICATION')
GROUP BY BS.SHIPMENT_GID,
AGSS.EVENTDATE,
D1SS.EVENTDATE,
BS.START_TIME,
AGSS.STATUS_CODE_GID,
D1SS.STATUS_CODE_GID,
BS.DOMAIN_NAME,
SHIPSTAT.STATUS_VALUE_GID
Query 2 (to be used as a sub-query if I cannot pull MAX insert date in previous query):
SELECT DISTINCT BS.SHIPMENT_GID AS BUY_SHIPMENT_GID,
AGSS.EVENTDATE AS AG_EVENT,
AGSS.STATUS_CODE_GID AS AG,
MAX(AGSS.INSERT_DATE) AS AG_INSERT_DATE
FROM V_ROD_SHIPMENT BS
INNER JOIN V_ROD_SS_STATUS_HISTORY AGSH
ON (BS.SHIPMENT_GID = AGSH.SHIPMENT_GID)
INNER JOIN V_ROD_IE_SHIPMENTSTATUS AGSS
ON (AGSH.I_TRANSACTION_NO = AGSS.I_TRANSACTION_NO)
WHERE AGSS.STATUS_CODE_GID = 'AG'
AND BS.SHIPMENT_GID = 'UPS/CP/HDMB.HDM-1000203768'
GROUP BY BS.SHIPMENT_GID,
AGSS.EVENTDATE,
AGSS.STATUS_CODE_GID
Results of query 2 (similar issue as query 1, query doesn't return MAX insert date):
BUY_SHIPMENT_GID AG_EVENT AG AG_INSERT_DATE
UPS/CP/HDMB.HDM-1000203768 5/25/2012 6:00:00 PM AG 5/21/2012 3:10:36 PM
UPS/CP/HDMB.HDM-1000203768 6/1/2012 5:00:00 PM AG 5/20/2012 2:36:18 PM
I appreciate any help.
Thanks,
-AdamHi, Adam,
Welcome to the forum!
Whenever you have a problem, please post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) from all tables involved.
Also post the results you want from that data, and an explanation of how you get those results from that data, with specific examples.
Simplify the problem as much as possible. Remove all tables and columns that play no role in this problem.
If you can show what the problem is using commonly available tables (such as those in the scott schem) then you don't have to psot any sample data; just the results and the explanation.
Always say which version of Oracle you're using.
See the forum FAQ {message:id=9360002}
MAX (insert_date) returns the latest insert_date. I think, in this problem, you don't really want the latest insert_date; you want the status code that's related to the last insert_date. One way to get that is the aggregate FIRST (or LAST) function.
Consider this query, using the scott.emp table:
SELECT ename
, hiredate
FROM scott.emp
ORDER BY hiredate
, ename
;Output:
ENAME HIREDATE
SMITH 17-Dec-1980
ALLEN 20-Feb-1981
WARD 22-Feb-1981
JONES 02-Apr-1981
BLAKE 01-May-1981
CLARK 09-Jun-1981
TURNER 08-Sep-1981
MARTIN 28-Sep-1981
KING 17-Nov-1981
FORD 03-Dec-1981
JAMES 03-Dec-1981
MILLER 23-Jan-1982
SCOTT 19-Apr-1987
ADAMS 23-May-1987Say we're only interested in seeing the last hiredate, and the name of the person hired on that date:
LAST_ENAME LAST_HIREDA
ADAMS 23-May-1987Here's how to get those results using the aggregate LAST function:
SELECT MIN (ename) KEEP (DENSE_RANK LAST ORDER BY hiredate) AS last_ename
, MAX (hiredate) AS last_hiredate
FROM scott.emp
;What if there's a tie for the latest hiredate? For example, say we're only looking at people hired before 1982. In that case, the latest hiredate is December 3, 1981, and there happen to be two people hired on that date. This query
SELECT MIN (ename) KEEP (DENSE_RANK LAST ORDER BY hiredate) AS last_ename
, MAX (hiredate) AS last_hiredate
FROM scott.emp
WHERE hiredate < DATE '1982-01-01'
;produces only 1 row of output:
LAST_ENAME LAST_HIREDA
FORD 03-Dec-1981Why did it show FORD rather than JAMES? Because of the MIN function. When there happens to be a tie for the latest hiredate, MIN says to return the first ename (in normal sort order) of the rows that have that hiredate.
FIRST and LAST work with GROUP BY, too.
In the example above, we were only looking at one column related to the latest hiredate. If we neede to see several columns, it would be simpler to use the analytic ROW_NUMBER function:
WITH got_r_num AS
SELECT emp.*
, ROW_NUMBER () OVER ( ORDER BY hiredate DESC
, ename
) AS r_num
FROM scott.emp
WHERE hiredate < DATE '1982-01-01'
SELECT *
FROM got_r_num
WHERE r_num = 1
I hope this answers your question.
If not, post a more complete explanation of what you want to do. if you have to use your own tables, then post CREATE TABLE and INSERT statements for a little sample data. Post the results you want from that data, and explain how you get those results from that data. -
Oracle 11g function based columns - deterministic function or not?
Hi all, here is my situation:
I added function based column in my table and created index on this column.
I need this since in my ADF application, I need to be able to sort by this column.
The function (that this column is based on) I had to make it DETERMINISTIC (otherwise it can not be done).
So far so good.
My function is accepting 3 parameters (all NUMBERs) which are practically 3 primary keys from 3 different tables. Based on which key is present, my function is returning "Code" - column (VARCHAR2) from any of those 3 tables. And for sure "Code" can change in any of those table.
So my function is not really a DETERMINISTIC function.
-Should I update the function and make it nondeterministic? Will it still work? Will the index be valid if the function is nondeterministic?
-What is the consequence if it is not deterministic?
-If I leave i as deterministic - somehow the result is cached. Will my function always going to be re-executed for each row (having on mind it is not really deterministic)?
-Is there better solution than (function based column and index on it) in my case?
Thanks, VesnaOK, Damorgan, here are some more details:
Versin Numbers:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
TABLE:
alter table MY_VIRTUAL_COLUMN add dispatch_customer_name GENERATED ALWAYS AS (get_dispatch_customer_name(disloc_id, cus_id, cusloc_id)) VIRTUAL;
create index dispatch_customer_name_i on MY_VIRTUAL_COLUMN(dispatch_customer_name);FUNCTION:
CREATE OR REPLACE FUNCTION get_dispatch_customer_name(p_disloc_id NUMBER,
p_cus_id NUMBER,
p_cusloc_id NUMBER)
RETURN VARCHAR2 DETERMINISTIC IS
v_result VARCHAR2(1000) := NULL;
BEGIN
IF p_cus_id IS NULL THEN
IF p_cusloc_id IS NULL THEN
SELECT d.name
INTO v_result
FROM dispatch_locations d
WHERE d.disloc_id = p_disloc_id;
ELSE
SELECT l.name || ' (' || l.code || ')'
INTO v_result
FROM customer_locations l
WHERE l.cusloc_id = p_cusloc_id;
END IF;
ELSE
SELECT s.name || ' (' || s.code || ')'
INTO v_result
FROM customers s
WHERE s.cus_id = p_cus_id;
END IF;
RETURN v_result;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END get_dispatch_customer_name;Hope this will help
Thanks, Vesna
Maybe you are looking for
-
My iPhone was stolen. How can I get my downloaded music if I had not transferred it to my laptop (not an iMac so no iCloud )
-
read title.
-
Recording Application in Flex + Web (HTTP/HTML) in LR11.52 Facing problem while parsing AMF binary code to XML. Uploaded flex-messaging-* jar files and application related jar files. The warning is "It is unable to instantiate the object com.db.lrc.
-
Hello! 1.I have set a rebate agreement with a quantity scale basis. (C) 2.I created a standard order and a billing document with material #AAA for a quantity of 100 TON and 10,000 $ value. 3. In the Rebate Agreement I checked the sales volume and cou
-
How do I set the inbox to list incoming mail in descending order
at present my emails are listing in no set order, its confusing and annoying is there an easy way for me to put this right?