Passing where and group by clause to cursor
I am working on a procedure that builds a where clause and needs a group by clause to return the correct results. I am trying to pass both the where and group by variables into the cursor.
The variables are getting populated correctly, but when the cursor gets created, the variables are not in the cursor.
Here is the code I'm working with. It is a part of a package, but makes no calls to other parts of the package.
PROCEDURE createFollowUpTask_Exposure( psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE default NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE default NULL,
psSubtyp IN tis.tial.subtyp%TYPE default NULL,
pnDays IN NUMBER default NULL,
psKampkod IN tis.tiin.kampkod%TYPE default NULL,
psKatnr IN tis.tiin.katnr%TYPE default NULL,
psUtgava IN tis.tiin.utgava%TYPE default NULL,
psKatslag IN tis.tikg.katslag%TYPE default NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE default NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE default NULL,
psProdkod IN tis.tiin.prodkod%TYPE default NULL,
psStatus IN tis.tiin.status%TYPE default NULL
) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount number := 0;
CURSOR cSqlSelect( SqlWhere IN VARCHAR2, GroupBy IN VARCHAR2) IS
SELECT tiin.kampkod, tiin.abnr, tiko.fordsalj, MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod AND tiin.abnr = tici.abnr AND tici.inplnr = tiin.inplnr
WHERE 1=1 || SqlWhere
GROUP BY GroupBy;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL and psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ '||pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.kampkod = '''|| psKampkod||'''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.katnr = '''||psKatnr||'''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.utgava = '''||psUtgava||'''' ;
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.katslag = '''||psKatslag||'''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tikg.prodsyst = '''||psProdsyst||'''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.uppgtyp = '''||psUppgtyp||'''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.prodkod = '''||psProdkod||'''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere||' AND tiin.status = '''||psStatus||'''';
END IF;
-- Loop through all records meeting input parameters and set required TIAL values.
FOR i IN cSqlSelect(vSqlWhere, vGroupBy)
LOOP
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: '||cTIAL.Kampkod||' '||cTIAL.Abnr||' Sales Rep: '||cTIAL.Alarmdate);
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('I created '||nCount||' records.');
END createFollowUpTask_Exposure;
Thanks in advance for any help.
Hi,
Welcome to the forum!
Try this (not tested) as an example:
PROCEDURE createFollowUpTask_Exposure(psUppgkedjetyp IN tis.tial.uppgkedjetyp%TYPE DEFAULT NULL,
psAlarmtyp IN tis.tial.alarmtyp%TYPE DEFAULT NULL,
psSubtyp IN tis.tial.subtyp%TYPE DEFAULT NULL,
pnDays IN NUMBER DEFAULT NULL,
psKampkod IN tis.tiin.kampkod%TYPE DEFAULT NULL,
psKatnr IN tis.tiin.katnr%TYPE DEFAULT NULL,
psUtgava IN tis.tiin.utgava%TYPE DEFAULT NULL,
psKatslag IN tis.tikg.katslag%TYPE DEFAULT NULL,
psProdsyst IN tis.tikg.prodsyst%TYPE DEFAULT NULL,
psUppgtyp IN tis.tiin.uppgtyp%TYPE DEFAULT NULL,
psProdkod IN tis.tiin.prodkod%TYPE DEFAULT NULL,
psStatus IN tis.tiin.status%TYPE DEFAULT NULL) AS
cTIAL tis.tial%ROWTYPE;
vLopnr tis.tial.lopnr%TYPE;
vSqlWhere VARCHAR2(4000);
vGroupBy VARCHAR2(1000) := ' tiin.kampkod, tiin.abnr, tiko.fordsalj';
cSelectCursor SYS_REFCURSOR;
vSqlSelect VARCHAR2(4000);
psDays VARCHAR2(50);
cRec T_TIAL_REC;
nCount NUMBER := 0;
FUNCTION fnc_cSqlSelect(SqlWhere IN VARCHAR2,
GroupBy IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN 'SELECT tiin.kampkod,
tiin.abnr,
tiko.fordsalj,
MAX(tici.regdat) ALARMDATE
FROM tis.tiin
JOIN tis.tiko ON tiin.kampkod = tiko.kampkod
AND tiin.abnr = tiko.abnr
JOIN core.tici ON tiin.kampkod = tici.kampkod
AND tiin.abnr = tici.abnr
AND tici.inplnr = tiin.inplnr
WHERE 1 = 1 ' || SqlWhere || ' GROUP BY ' || GroupBy;
END fnc_cSqlSelect;
BEGIN
-- If these parameters are null, raise error
IF psUppgkedjetyp IS NULL AND psSubtyp IS NULL THEN
raise_application_error(-20001,
'Either Event Chain or Starting Event must be assigned');
END IF;
-- Populate TIAL values
IF psUppgkedjetyp IS NOT NULL THEN
cTIAL.Uppgkedjetyp := psUppgkedjetyp;
END IF;
IF psAlarmtyp IS NOT NULL THEN
cTIAL.Alarmtyp := psAlarmtyp;
END IF;
cTIAL.Handklass := 'T';
cTIAL.Blobid := 0;
IF pnDays IS NOT NULL THEN
psDays := '+ ' || pnDays;
END IF;
IF psSubtyp IS NOT NULL THEN
cTIAL.Subtyp := psSubtyp;
END IF;
-- Create Where clause for cursor
vSqlWhere := '';
IF psKampkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.kampkod = ''' || psKampkod || '''';
END IF;
IF psKatnr IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.katnr = ''' || psKatnr || '''';
END IF;
IF psUtgava IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.utgava = ''' || psUtgava || '''';
END IF;
IF psKatslag IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.katslag = ''' || psKatslag || '''';
END IF;
IF psProdsyst IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tikg.prodsyst = ''' || psProdsyst || '''';
END IF;
IF psUppgtyp IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.uppgtyp = ''' || psUppgtyp || '''';
END IF;
IF psProdkod IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.prodkod = ''' || psProdkod || '''';
END IF;
IF psStatus IS NOT NULL THEN
vSqlWhere := vSqlWhere || ' AND tiin.status = ''' || psStatus || '''';
END IF;ç
-- Loop through all records meeting input parameters and set required TIAL values.
OPEN cSelectCursor FOR fnc_cSqlSelect(vSqlWhere,
vGroupBy);
LOOP
FETCH cSelectCursor
INTO v; -- You must define a variable 'v' to hold the data of cursor
EXIT WHEN cSelectCursor%NOTFOUND;
--FETCH cSelectCursor INTO cRec;
cTIAL.Kampkod := '';
cTIAL.Abnr := '';
cTIAL.Sign := '';
cTIAL.Alarmdate := '';
cTIAL.Kampkod := i.Kampkod;
cTIAL.Abnr := i.Abnr;
cTIAL.Sign := i.fordsalj;
cTIAL.Alarmdate := i.alarmdate;
nCount := nCount + 1;
IF vLopnr = -1 THEN
raise_application_error(-20002,
'Error Creating task for: ' || cTIAL.Kampkod || ' ' ||
cTIAL.Abnr || ' Sales Rep: ' || cTIAL.Alarmdate);
END IF;
END LOOP;
CLOSE cSelectCursor;
DBMS_OUTPUT.PUT_LINE('I created ' || nCount || ' records.');
END createFollowUpTask_Exposure;
/Regards,
Similar Messages
-
Creation of view with clob column in select and group by clause.
Hi,
We are trying to migrate a view from sql server2005 to oracle 10g. It has clob column which is used in group by clause. How can the same be achived in oracle 10g.
Below is the sql statament used in creating view aling with its datatypes.
CREATE OR REPLACE FORCE VIEW "TEST" ("CONTENT_ID", "TITLE", "KEYWORDS", "CONTENT", "ISPOPUP", "CREATED", "SEARCHSTARTDATE", "SEARCHENDDATE", "HITS", "TYPE", "CREATEDBY", "UPDATED", "ISDISPLAYED", "UPDATEDBY", "AVERAGERATING", "VOTES") AS
SELECT content_ec.content_id,
content_ec.title,
content_ec.keywords,
content_ec.content content ,
content_ec.ispopup,
content_ec.created,
content_ec.searchstartdate,
content_ec.searchenddate,
COUNT(contenttracker_ec.contenttracker_id) hits,
contenttypes_ec.type,
users_ec_1.username createdby,
Backup_Latest.created updated,
Backup_Latest.isdisplayed,
users_ec_1.username updatedby,
guideratings.averagerating,
guideratings.votes
FROM users_ec users_ec_1
JOIN Backup_Latest
ON users_ec_1.USER_ID = Backup_Latest.USER_ID
RIGHT JOIN content_ec
JOIN contenttypes_ec
ON content_ec.contenttype_id = contenttypes_ec.contenttype_id
ON Backup_Latest.content_id = content_ec.content_id
LEFT JOIN guideratings
ON content_ec.content_id = guideratings.content_id
LEFT JOIN contenttracker_ec
ON content_ec.content_id = contenttracker_ec.content_id
LEFT JOIN users_ec users_ec_2
ON content_ec.user_id = users_ec_2.USER_ID
GROUP BY content_ec.content_id,
content_ec.title,
content_ec.keywords,
to_char(content_ec.content) ,
content_ec.ispopup,
content_ec.created,
content_ec.searchstartdate,
content_ec.searchenddate,
contenttypes_ec.type,
users_ec_1.username,
Backup_Latest.created,
Backup_Latest.isdisplayed,
users_ec_1.username,
guideratings.averagerating,
guideratings.votes;
Column Name Data TYpe
CONTENT_ID NUMBER(10,0)
TITLE VARCHAR2(50)
KEYWORDS VARCHAR2(100)
CONTENT CLOB
ISPOPUP NUMBER(1,0)
CREATED TIMESTAMP(6)
SEARCHSTARTDATE TIMESTAMP(6)
SEARCHENDDATE TIMESTAMP(6)
HITS NUMBER
TYPE VARCHAR2(50)
CREATEDBY VARCHAR2(20)
UPDATED TIMESTAMP(6)
ISDISPLAYED NUMBER(1,0)
UPDATEDBY VARCHAR2(20)
AVERAGERATING NUMBER
VOTES NUMBERAny help realyy appreciated.
Thanks in advance
Edited by: user512743 on Dec 10, 2008 10:46 PMHello,
Specifically, this should be asked in the
ASP.Net MVC forum on forums.asp.net.
Karl
When you see answers and helpful posts, please click Vote As Helpful, Propose As Answer, and/or Mark As Answer.
My Blog: Unlock PowerShell
My Book: Windows PowerShell 2.0 Bible
My E-mail: -join ('6F6C646B61726C40686F746D61696C2E636F6D'-split'(?<=\G.{2})'|%{if($_){[char][int]"0x$_"}}) -
Passing parameters in order by clause of cursor
Hi friends,
I am facing a strange problem
I have a cursor with a order by clause.
OPEN cursor_nomrpt FOR
SELECT DISTINCT
CAST(plano.desc3 AS VARCHAR2(50)) category
,plano.name plan_name
,nvl(CAST(plano.desc6 AS VARCHAR2(50)),'not applicable') pcrr
,nvl(trunc(plano.value18,2),0) nominal_slm
,nvl(trunc(plano.value19,2),0) blm
,plano.dbdateeffectivefrom date_live
plano.dbkey pog_id
,case when plano.value47 < 0 THEN 0 when plano.value47 IS NULL THEN 0 ELSE plano.value47 END AS parent_id
FROM
dplapro1.ix_spc_planogram plano
INNER JOIN dplapro1.ix_spc_performance perf ON plano.dbkey = perf.dbparentplanogramkey
INNER JOIN dplapro1.ix_spc_product product ON perf.dbparentproductkey = product.dbkey
INNER JOIN dplapro1.ix_spc_product_key prodkey ON product.dbkey2 = prodkey.dbkey
AND prodkey.keylevel = 2
WHERE
plano.value50 = 0
AND plano.dbkey4 = p_subcatkey
ORDER BY ltrim(rtrim(p_orderby)) ASC;
p_orderby is the parameter being passed. But the output is not sorted. But when I run the cursor by hardcoding the parameter value it works fine...
Need your help on thisHi,
When you use a local variable in a cursor, it's as if you had hard-coded a literal in its place, so you can't use a variable for a column name.
If you know all the possible values of p_orderby, you can do something like this:
ORDER BY TRIM ( CASE p_orderby
WHEN 'DESC' THEN plano.desc
WHEN 'VALUE' THEN plano.value
END
) ASC;If you don't know all the possible values, you could use dynamic SQL.
By the way,
TRIM (x)returns the same results as
LTRIM ( RTRIM (x)) -
Need help in optimizing the query with joins and group by clause
I am having problem in executing the query below.. it is taking lot of time. To simplify, I have added the two tables FILE_STATUS = stores the file load details and COMM table that is actual business commission table showing records successfully processed and which records were transmitted to other system. Records with status = T is trasnmitted to other system and traansactions with P is pending.
CREATE TABLE FILE_STATUS
(FILE_ID VARCHAR2(14),
FILE_NAME VARCHAR2(20),
CARR_CD VARCHAR2(5),
TOT_REC NUMBER,
TOT_SUCC NUMBER);
CREATE TABLE COMM
(SRC_FILE_ID VARCHAR2(14),
REC_ID NUMBER,
STATUS CHAR(1));
INSERT INTO FILE_STATUS VALUES ('12345678', 'CM_LIBM.TXT', 'LIBM', 5, 4);
INSERT INTO FILE_STATUS VALUES ('12345679', 'CM_HIPNT.TXT', 'HIPNT', 4, 0);
INSERT INTO COMM VALUES ('12345678', 1, 'T');
INSERT INTO COMM VALUES ('12345678', 3, 'T');
INSERT INTO COMM VALUES ('12345678', 4, 'P');
INSERT INTO COMM VALUES ('12345678', 5, 'P');
COMMIT;Here is the query that I wrote to give me the details of the file that has been loaded into the system. It reads the file status and commission table to show file name, total records loaded, total records successfully loaded to the commission table and number of records that has been finally transmitted (status=T) to other systems.
SELECT
FS.CARR_CD
,FS.FILE_NAME
,FS.FILE_ID
,FS.TOT_REC
,FS.TOT_SUCC
,NVL(C.TOT_TRANS, 0) TOT_TRANS
FROM FILE_STATUS FS
LEFT JOIN
SELECT SRC_FILE_ID, COUNT(*) TOT_TRANS
FROM COMM
WHERE STATUS = 'T'
GROUP BY SRC_FILE_ID
) C ON C.SRC_FILE_ID = FS.FILE_ID
WHERE FILE_ID = '12345678';In production this query has more joins and is taking lot of time to process.. the main culprit for me is the join on COMM table to get the count of number of transactions transmitted. Please can you give me tips to optimize this query to get results faster? Do I need to remove group and use partition or something else. Please help!I get 2 rows if I use my query with your new criteria. Did you commit the record if you are using a second connection to query? Did you remove the criteria for file_id?
select carr_cd, file_name, file_id, tot_rec, tot_succ, tot_trans
from (select fs.carr_cd,
fs.file_name,
fs.file_id,
fs.tot_rec,
fs.tot_succ,
count(case
when c.status = 'T' then
1
else
null
end) over(partition by c.src_file_id) tot_trans,
row_number() over(partition by c.src_file_id order by null) rn
from file_status fs
left join comm c
on c.src_file_id = fs.file_id
where carr_cd = 'LIBM')
where rn = 1;
CARR_CD FILE_NAME FILE_ID TOT_REC TOT_SUCC TOT_TRANS
LIBM CM_LIBM.TXT 12345678 5 4 2
LIBM CM_LIBM.TXT 12345677 10 0 0Using RANK can potentially produce multiple rows to be returned though your data may prevent this. ROW_NUMBER will always prevent duplicates. The ordering of the analytical function is irrelevant in your query if you use ROW_NUMBER. You can remove the outermost query and inspect the data returned by the inner query;
select fs.carr_cd,
fs.file_name,
fs.file_id,
fs.tot_rec,
fs.tot_succ,
count(case
when c.status = 'T' then
1
else
null
end) over(partition by c.src_file_id) tot_trans,
row_number() over(partition by c.src_file_id order by null) rn
from file_status fs
left join comm c
on c.src_file_id = fs.file_id
where carr_cd = 'LIBM';
CARR_CD FILE_NAME FILE_ID TOT_REC TOT_SUCC TOT_TRANS RN
LIBM CM_LIBM.TXT 12345678 5 4 2 1
LIBM CM_LIBM.TXT 12345678 5 4 2 2
LIBM CM_LIBM.TXT 12345678 5 4 2 3
LIBM CM_LIBM.TXT 12345678 5 4 2 4
LIBM CM_LIBM.TXT 12345677 10 0 0 1 -
Error in query with COUNT expression and Group By Clause
Hi
I have this query that when run gives me the following error:
SQL command not properly ended:
The code is as below:
SELECT
st_enrollment.student_id ,
ce_family_member.last_name ,
st_enrollment.grade_level ,
ce_family_member.DATE_OF_BIRTH ,
ce_family_member.GENDER,
at_hourly_attendance_records.ABSENCE_REASON_CODE,
at_hourly_attendance_records.CALENDAR_DATE,
COUNT(st_enrollment.student_id) AS days_absent
FROM
at_hourly_attendance_records,
ce_family_member,
st_enrollment
WHERE
st_enrollment.student_id = at_hourly_attendance_records.student_id
AND ce_family_member.student_id = st_enrollment.student_id
AND st_enrollment.school_id = 705
AND st_enrollment.school_year = 2006
AND st_enrollment.district_number = 1000
AND at_hourly_attendance_records.ATTENDANCE_STATUS = 'A'
AND at_hourly_attendance_records.CALENDAR_DATE < '16-MAR-06'
GROUP BY st_enrollment.student_id,
ce_family_member.last_name
st_enrollment.grade_level ,
ce_family_member.DATE_OF_BIRTH ,
ce_family_member.GENDER,
at_hourly_attendance_records.ABSENCE_REASON_CODE,
at_hourly_attendance_records.CALENDAR_DATE;
All suggestions are gratefully acknowledgment, Thanks in advanceThanks a lot. In fact I discovered it myself and I am immensely grateful to you for pointing the error..
-
SQL Server SUM of Multiple rows with where and group by
I have a table Transaction that looks something like the following :
TransactionID
Currency
Credit
Debit
1 USD
500 0
2 Afcu
6000 0
3 INR
0 200
4 Pfc
7000 0
5 AUD
0 200
6 INR
7000 0
7 USD
1000 0
I write query like this
select SUM(credit)-SUM(Debit)as [Balance] ,Source from Transaction group by Source
and it came like
Balance
Source
1500 USD
6000 Afcu
6800 INR
7000 Pfc
-200 AUD
But I also want to add Afcu , Pfc with
USD and want output like
Balance
Source
14500 USD
6800 INR
-200 AUD
Any Idea?Here is how you can do it, but you
DECLARE @TransTable TABLE
(TransactionID INT IDENTITY(1,1),
Currency varchar(10),
Credit DECIMAL,
Debit DECIMAL)
INSERT INTO @TransTable VALUES
('USD',500,0),('Afcu',6000,0),('INR',0,200),('Pfc',7000,0),('AUD',0,200),
('INR',7000,0),('USD',1000,0)
SELECT Currency, SUM(credit)-SUM(Debit)as [Balance]
FROM @TransTable
WHERE Currency NOT IN ('Afcu', 'pfc','USD')
GROUP BY Currency
UNION
SELECT 'USD', SUM(credit)-SUM(Debit)as [Balance]
FROM @TransTable
WHERE Currency IN ('Afcu', 'pfc','USD')
SQL fiddler example
Output:
Hope this will help
Glad to help! Please remember to accept the answer if you found it helpful. It will be useful for future readers having same issue.
My Profile on Microsoft ASP.NET forum -
Group by clause will try to group the primay key's
hi all,
For my requiremments and to avoid the the subquery i am using join and group by clause in my sql query in oracle 10g r2 database.my question is if i put a primary column the group clause then oracle try to group the records?.
i know if we use a primary key column in group by clause there is no grouping will occur.
but i have doubt oracle will try to group ? because it will take some amount of time to achive?
else due presense of primay key column in group by clause oracle won't try?
Please advice ??My query return the records less then the min v_date(date datatype) column.
i check this condition in having clause
my old query is
select emp_id,emp_name,voldate,volume,productivity
from volume v1
where v1.voldate<=(select min(v2.voldate) form volume v2 where v2.emp_id=1)
and v1.emp_id=1
i change it as
select emp_id,emp_name,voldate,volume,productivity
from volume v1,volume v2
where v1.emp_id=v2.emp_id
having v1.voldate<=min(v2. voldate)
group by emp_id,emp_name,voldate,volume,productivity
above the query's emp_id is primay key for volume table
comparing both query's which one is the best while looking th response time.
else any other alternative for both the queries.?? -
Rewrite the query with out joins and group by
Hi,
This was an interview question.
Table Names: bookshelf_checkout
bookshelf
And the join condition between these two tables is title
We need to rewrite below query without using join condition and group by clause ?
SELECT b.title,max(bc.returned_date - bc.checkout_date) "Most Days Out"
FROM bookshelf_checkout bc,bookshelf b
WHERE bc.title(+)=b.title
GROUP BY b.title;When I was in college, I read that most of the SELECT statements can be replaced by basic SQL operations (SET OPERATORS). Now I am trying to rewrite the query with SET operators but not able to get the exact result.
Kindly help me on this.
Thanks,
SuriSomething like this?
1 WITH books AS (
2 SELECT 'title 1' title FROM dual UNION ALL
3 SELECT 'title 2' FROM dual UNION ALL
4 SELECT 'title 3' FROM dual ),
5 bookshelf AS (
6 SELECT 'title 1' title, DATE '2012-05-01' checkout_date, DATE '2012-05-15' returned_date FROM dual UNION ALL
7 SELECT 'title 1' title, DATE '2012-05-16' checkout_date, DATE '2012-05-20' returned_date FROM dual UNION ALL
8 SELECT 'title 2' title, DATE '2012-04-01' checkout_date, DATE '2012-05-15' returned_date FROM dual )
9 SELECT bs.title, MAX(bs.returned_date - bs.checkout_date) OVER (PARTITION BY title) FROM bookshelf bs
10 UNION
11 (SELECT b.title, NULL FROM books b
12 MINUS
13* SELECT bs.title, NULL FROM bookshelf bs)
SQL> /
TITLE MAX(BS.RETURNED_DATE-BS.CHECKOUT_DATE)OVER(PARTITIONBYTITLE)
title 1 14
title 2 44
title 3Lukasz -
Passing where clause of cursor
my requirement is that i want to declare a cursor but the problem is that where clause of sql statement of cursor is dynamically generated according to user clicks........ e. g. number of conditions in where clause may change.....
so..... how can i declare the cursor...how do i pass where clause to any procedure if i write procedure or function......u can use for-loop cursors like this,
for v_rec in 'select * from emp where' || ur_conditions ||'
see oracle documentation for further help and examples -
Passing where cluase as parameter for cursor
I want to pass where clause of cursor as parameter.... how can I do that?
say I want cursor as,
cursor c1 is select fname, mname from person where :param;
where :param is a value I want to pass in declare sectionI want to pass where clause of cursor as parameter.... how can I do that?Yes.
cursor c1 is select fname, mname from person where :param;
where :param is a value I want to pass in declare sectionYou can also shoot yourself in the foot using a 357 Magnum.
Neither is recommended - unless you are a professional idiot. Which I doubt as these are typically your Darwin Award Winners.
Why is it bad to to have "+WHERE :param+"?
Bind variables. If the WHERE clause is passed as a dynamic string. this will usually be implemented in the following fashion:
SQL> create or replace procedure smellyFoo( filterClause varchar2, refCur in out sys_refcursor ) is
2 begin
3 open refCur for
4 'select owner, object_id, object_name from all_objects where owner != ''SYS'' and '||filterClause||' order by 1,2';
5 end;
6 /
Procedure created.
SQL>
SQL> var c refcursor
SQL> exec smellyFoo( 'object_type=''TABLE'' and rownum <11', :c );
PL/SQL procedure successfully completed.
SQL>
SQL> print c
OWNER OBJECT_ID OBJECT_NAME
OUTLN 452 OL$
OUTLN 453 OL$HINTS
OUTLN 456 OL$NODES
SYSTEM 3621 MVIEW$_ADV_WORKLOAD
SYSTEM 3624 MVIEW$_ADV_BASETABLE
SYSTEM 3626 MVIEW$_ADV_SQLDEPEND
SYSTEM 3628 MVIEW$_ADV_PRETTY
SYSTEM 3630 MVIEW$_ADV_TEMP
SYSTEM 3632 MVIEW$_ADV_FILTER
SYSTEM 3634 MVIEW$_ADV_LOG
10 rows selected.
SQL>What's wrong with this? The filter clause contains literals. Not bind variables. Which means that non-sharable SQL will be created. This means more cursors (for same SQLs with different literal values) in the shared pool. Different sizes SQLs that leads to fragmentation of the shared pool memory. More hard parsing. Bigger delay in parsing as there are more cursors to scan in the shared pool (useless exercise) as there are no existing cursors that are sharable and can be re-used.
So what would the correct way be? The client passing a filter clause as a proper bind variable string, and also passing (separately) the values for those bind variables. But this is not easy to code, especially when dealing with filter clauses that may contain no bind variables. or a 100 bind variables.
Also, the call interface the client needs to use will become a lot more complex as the client now not only needs to build a proper string containing bind variables, it also need to make sure it pass the values for those variables in the correct order.
So why? Why do any of this? What is the requirement that lead you to this "solution" where the client can dynamically decide on what the filter criteria is?
Surely, there must be a reason to this madness of the client wanting to throw any filter clause at a SQL cursor... and surely, that is what needs to be identified and analysed and resolved - instead of wanting to create hacks like the above. Causing performance issues. Not to mention opening a security hole that is ideal for SQL injection. -
Which two statements are true about WHERE and HAVING clause ?
Which two statements are true about WHERE and HAVING clause ?
1. WHERE clause can be used to restict rows only
2.HAVING clause can be used to restrict groups only
3.HAVING clause can be used to restrict groups and rows
Plz help me in dis ques...which two will be correct...i think its 1 and 2...but not sure.863180 wrote:
Plz help me in dis ques...which two will be correct...i think its 1 and 2...but not sure.If you are not sure then you do not fully understand HAVING.
SY. -
3 Table Join with group by and order by clauses
I am porting from MySQL to Oracle 8i. I have a three Table Join in MySQL as follows:
select distinct TO_DAYS(l.listend)-TO_DAYS(NOW()) AS daysLeft, i.minbid, l.listend, i.itemid, i.itemtitle, l.listingid, l.lendstart, l.lendend, l.status, MAX(b.amount) AS curBid, COUNT(b.amount) AS numBids from TBL_ITEMS i, TBL_LISTING l LEFT JOIN TBL_BIDS b ON l.listingid=b.listingid where i.itemid = l.itemid AND l.status='1' AND (TO_DAYS(l.listend)-TO_DAYS(NOW()) >= 0) AND i.catcode LIKE'12__' GROUP BY listingid order by curBid DESC, daysLeft;
It performs an straight join on the first 2 tables (TBL_ITEMS and TBL_LISTING) and a LEFT JOIN between the previous result set and TBL_BIDS. TBL_BIDS uses a group by clause to obtain MAX and COUNT info. This final result set is the sorted (ORDER BY).
I have tried to reconstruct this type of call in Oracle and have failed. Several problems that I have notices: Oracle does not let me pull in additional columns when doing a GROUP BY clause.
(see below for my work around)
I have worked around the problem by creating a TABLE with the group by functionality and doing a straing 3 table join. (NOTE: I cannot create a view because use a LIKE function in the call... view dont have indexes). However, when I try to alias the column that returns DATE subtraction ("l.listend-TRUNC(SYSDATE) daysLeft" OR "l.listend-TRUNC(SYSDATE) dayLeft") I cannot use the LIKE statement.
Here is my question. How do I port the above 3-table MySQL call to Oracle. Why am I having these problems (is it the Oracle optimizer?) and how do I avaopid them in the future.
I really appreciate anyone's input. Thanks,
Inder
WORK AROUND:
FIRST STEP:
"create TABLE BIDSUM as
select l.listingid, COUNT(b.amount) numBids, MAX(b.amount) curBid from TBL_LISTING l, TBL_BIDS b where l.listingid=b.listingid(+) group by (l.listingid);"
NEXT STEP:
select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE), l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode LIKE '12%';
THIS ALSO WORKS (no LIKE):
"select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE) daysLeft, l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode='12'";
BUT THIS DOES NOT (alias the DATE arimetic)
select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE) daysLeft, l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode LIKE '12__';I am porting from MySQL to Oracle 8i. I have a three Table Join in MySQL as follows:
select distinct TO_DAYS(l.listend)-TO_DAYS(NOW()) AS daysLeft, i.minbid, l.listend, i.itemid, i.itemtitle, l.listingid, l.lendstart, l.lendend, l.status, MAX(b.amount) AS curBid, COUNT(b.amount) AS numBids from TBL_ITEMS i, TBL_LISTING l LEFT JOIN TBL_BIDS b ON l.listingid=b.listingid where i.itemid = l.itemid AND l.status='1' AND (TO_DAYS(l.listend)-TO_DAYS(NOW()) >= 0) AND i.catcode LIKE'12__' GROUP BY listingid order by curBid DESC, daysLeft;
It performs an straight join on the first 2 tables (TBL_ITEMS and TBL_LISTING) and a LEFT JOIN between the previous result set and TBL_BIDS. TBL_BIDS uses a group by clause to obtain MAX and COUNT info. This final result set is the sorted (ORDER BY).
I have tried to reconstruct this type of call in Oracle and have failed. Several problems that I have notices: Oracle does not let me pull in additional columns when doing a GROUP BY clause.
(see below for my work around)
I have worked around the problem by creating a TABLE with the group by functionality and doing a straing 3 table join. (NOTE: I cannot create a view because use a LIKE function in the call... view dont have indexes). However, when I try to alias the column that returns DATE subtraction ("l.listend-TRUNC(SYSDATE) daysLeft" OR "l.listend-TRUNC(SYSDATE) dayLeft") I cannot use the LIKE statement.
Here is my question. How do I port the above 3-table MySQL call to Oracle. Why am I having these problems (is it the Oracle optimizer?) and how do I avaopid them in the future.
I really appreciate anyone's input. Thanks,
Inder
WORK AROUND:
FIRST STEP:
"create TABLE BIDSUM as
select l.listingid, COUNT(b.amount) numBids, MAX(b.amount) curBid from TBL_LISTING l, TBL_BIDS b where l.listingid=b.listingid(+) group by (l.listingid);"
NEXT STEP:
select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE), l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode LIKE '12%';
THIS ALSO WORKS (no LIKE):
"select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE) daysLeft, l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode='12'";
BUT THIS DOES NOT (alias the DATE arimetic)
select i.minbid, i.itemtitle, l.lendstart-TRUNC(SYSDATE) daysLeft, l.lendend, l.listingid, l.status, s.numbids, s.curbid from TBL_ITEMS i, TBL_LISTING l, BIDSUM s where l.listingid=s.listingid AND i.itemid=l.itemid AND l.status='1' AND i.catcode LIKE '12__'; -
GROUP BY clause diff in Sybase and Oracle
Hi,
I am migrating code from Sybase to Oracle and came across a strange issue which is widely known to others :)
In Sybase , one can use columns or calculations in the SELECT expressions that don't appear
in the GROUP BY clause of the query. Like
SELECT order.custid,customer.name,MAX(payments)
-> FROM order, customer
-> WHERE order.custid = customer.custid
-> GROUP BY order.custid;
works fine but for SQL we need to add customer.name to GROUP BY clause.
On the similar lines, here is my SQL query
INSERT INTO GTT_CTRT_recalc_proc
(id_fin_rec,
id_imnt,
id_instr_opn,
dt_instr_opn,
dt_opn,
dt_cls_loanet,
dt_prcss,
am_invst)
SELECT t1.id_fin_rec,
t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
NVL(t1.dt_cls_loanet, l_dt_to),
t1.dt_prcss,
SUM(t2.am_invst) + (0.123 * (1 - abs(sign(0 - SUM(t2.am_invst)))))
FROM GTT_CTRT_TEMP_recalc_process t1, GTT_CTRT_TEMP_recalc_process t2
WHERE t2.id <= t1.id
AND t2.id_imnt = t1.id_imnt
AND t2.id_instr_opn = t1.id_instr_opn
AND t2.dt_instr_opn = t1.dt_instr_opn
GROUP BY t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
t1.dt_cls_loanet,
t1.dt_prcss;
Which does not have t1.id_fin_rec in GROUP BY failing it in SQL.
I know that if I add this column in GROUP BY it will work fine but I am told to keep the functionality as it is as the result before and after adding the column would be diff of-course.
Please guide me about what can be done in this situation and is there any work around for this?
Thanks,
AashishThat's a piece of nasty denormalisation. We shoudl also expect trouble we do stuff like that. Anyway, I think encapsulating the stuff from T2 into an inline view should sort you out....
INSERT INTO GTT_CTRT_recalc_proc
(id_fin_rec,
id_imnt,
id_instr_opn,
dt_instr_opn,
dt_opn,
dt_cls_loanet,
dt_prcss,
am_invst)
SELECT t1.id_fin_rec,
t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
NVL(t1.dt_cls_loanet, l_dt_to),
t1.dt_prcss,
, t2.total
FROM GTT_CTRT_TEMP_recalc_process t1
, ( select id_imnt,
id_instr_opn,
dt_instr_opn,
SUM(am_invst) + (0.123 * (1 - abs(sign(0 - SUM(am_invst))))) AS total
FROM GTT_CTRT_TEMP_recalc_process
GROUP BY id_imnt,
id_instr_opn,
dt_instr_opn ) t2
WHERE t2.id <= t1.id
AND t2.id_imnt = t1.id_imnt
AND t2.id_instr_opn = t1.id_instr_opn
AND t2.dt_instr_opn = t1.dt_instr_opn
GROUP BY t1.id_imnt,
t1.id_instr_opn,
t1.dt_instr_opn,
t1.dt_opn,
t1.dt_cls_loanet,
t1.dt_prcss;Cheers, APC
blog: http://radiofreetooting.blogspot.com
Edited by: APC on Mar 16, 2009 2:31 PM
Forgot to include GROUP BY in the inline view -
Hi,
I have wriiten the below query and i am using group by and order by clause....but i am not getting the required result
SELECT b.ACCOUNT_REGION,CASE WHEN b.product_reference_status='Reference' THEN 'Recruited' WHEN b.product_reference_status in ('Inactive','Declined') THEN 'Inactive' WHEN b.product_reference_status ='Nominate' THEN 'Inprogress' ELSE 'Other' END product_reference_status, COUNT(decode(b.product_quarter,'Q1FY09',b.REFERENCE_ID)) Q1FY09, COUNT(decode(b.product_quarter,'Q2FY09',b.REFERENCE_ID)) Q2FY09, COUNT(decode(b.product_quarter,'Q3FY09',b.REFERENCE_ID)) Q3FY09, COUNT(decode(b.product_quarter,'Q4FY09',b.REFERENCE_ID)) Q4FY09, COUNT(decode(b.product_quarter,'Q1FY10',b.REFERENCE_ID)) Q1FY10, COUNT(decode(b.product_quarter,'Q2FY10',b.REFERENCE_ID)) Q2FY10, COUNT(decode(b.product_quarter,'Q3FY10',b.REFERENCE_ID)) Q3FY10, COUNT(decode(b.product_quarter,'Q4FY10',b.REFERENCE_ID)) Q4FY10, COUNT(b.product_quarter) Total
FROM refdump a, ref_dh_pr b
WHERE A.REFERENCE_ID=b.REFERENCE_ID AND (b.CREATED_ON - NVL(a.REFERENCE_DATE,a.CREATED))>15 group by b.account_region,product_reference_status order by 2
output is as given below
Region Status Count
LAD Inactive 0
EMEA Inactive 21
*APAC Inactive 2
*APAC Inactive 1
EMEA Inactive 2
EMEA Inprogress 220
LAD Inprogress 19
LAD Other 2
LAD Other 0
LAD Other 5
LAD Recruited 182
APAC Recruited 191
My question is
1) Why i am geeting two APAC regions and 3 LAD (marked *) regions when i have grouped by region and status
2) How can i make the status in the following order
a) Recruited
b)Inprogress
c)Inactive
d)Other
Thanks,<i>group by b.account_region,product_reference_status</i>
Just take all the columns in the group by clause in your select segment and run the SQL, you'll come to know abt the different values in columns which group together.
*009* -
Passing where clause with spaces from forms to reports
Hi,
Has anybody passed where clause as lexical parameter with spaces from forms to preports..
I have seen people mention that, we can replace the spaces with special characters and then replace it again in the before trigger report..does anyone have a working example of that??
Thanks.i solved the issue..
i had written the procedure in the before report
trigger instead of writing it in the before parameter
form trigger..
it works perfecto now..
Thanks.We had removed the spaces and used commas to delimit each item.
So you are saying spaces are not a problem in 10g?
Maybe you are looking for
-
I use iphone5, I see an app update on the app store. but when App store and click on the update tab, it doesn't show me which application to update.. just gives me a blank page.!!!! I wouldn't able to know what app has to be updated, untill and unles
-
FOREIGN CURRENCY TRANSACTION CODE AND IN FBL1N
Hi All, Can some one advise me what is the T Code to display Foreign exchange rates for different Currencies and how to display the another currency in FBL1N apart from the local currency. Regards, Srikanth Moderator: Please, avoid asking basic quest
-
Bapi function module for ME32k Transaction
Hi all, Can any one tell me what is the BAPI function module for ME32K transaction . I am trying to create service agreements in this transaction. Even you can tell me if any other alternative procedure is there to create the service agreemen
-
What is the best practice when any of Src/Tgt DB is re-started in streams
We have a live production dual direction streams environment (A --> B and B --> A) and due to a DBFcorrupt file at source A, it was brought down and all traffic was switched to B. All streams captures,prop and apply were enabled and messages were cap
-
SJC2 & MSSQL 2005 : pagesize()
Hi all, In the editor I am just creating a dataprovider on a database table and a jsp page with a table to display the data (just drag/drop). It works! So if I modify the default 0 value of property Pagesize of the CachedRowset, I recieve the followi