PL/SQL: Conditional Where - asp.net

I have the following scenario:
CREATE OR REPLACE PROCEDURE GETINBOX
(
inHasAttachments IN int
)
AS
BEGIN
SELECT M.MailId,
M.SenderId,
E.Emp_Name As "Sender",
MI.RecipientId,
M.Subject
FROM MAIL M INNER JOIN MAILINBOX MI ON M.MailId = MI.MailId
WHERE MI.RecipientId = '547' AND
M.NotificationSelected = 'Y'
IF inHasAttachments = '1' THEN
AND M.Attachments = 'Y'
END IF;
END GETINBOX;
Is it possible to add conditions to the where clause based on the value of a parameter?
WHERE MI.RecipientId = '547' AND
M.NotificationSelected = 'Y'
IF inHasAttachments = '1' THEN
AND M.Attachments = 'Y'
END IF;
Obviously this is not allowed but is it possible to do this in some way in PL/SQL?
I know one way to do it is to duplicate the query and execute a different query based on the value of the parameter but I don't want to duplicate my code.

As I understand your requirements: if the value of parameter inHasAttachments is 1 then you want to filter further by M.Attachments = 'Y', and if its value isn't 1 then you don't care about M.Attachments. This is in addition to the condition MI.RecipientId = '547' AND M.NotificationSelected = 'Y'.
You can do it like this:
SELECT M.MailId,
M.SenderId,
E.Emp_Name As "Sender",
MI.RecipientId,
M.Subject
FROM MAIL M INNER JOIN MAILINBOX MI ON M.MailId = MI.MailId
WHERE MI.RecipientId = '547' AND M.NotificationSelected = 'Y'
AND (inHasAttachments <> '1' OR M.Attachments = 'Y')

Related

Assign variable error if 'no rows selected' from query

I want to assign a variable from the sale of today by the menu item input. If the menu item has been sold yet, the variable should return 0. But it showed error instead:
Error report -
SQL Error: ORA-00905: missing keyword
00905. 00000 - "missing keyword"
This is my code:
SELECT SUM(Selling_Price*Quantity_Sold)
INTO V_Today_Sale
FROM Bill_Item BI, Bill B
WHERE BI.Bill_Number = B.Bill_Number AND
Menu_Item_Number = 1 AND
Bill_Date = sysdate AND
(NVL(Paid_YN,'N') = 'Y' OR NVL(Posted_YN,'N') = 'Y')
GROUP BY Menu_Item_Number
ORDER BY Menu_Item_Number;
If I remove the variable assignment
SELECT SUM(Selling_Price*Quantity_Sold)
FROM Bill_Item BI, Bill B
WHERE BI.Bill_Number = B.Bill_Number AND
Menu_Item_Number = 1 AND
Bill_Date = sysdate AND
(NVL(Paid_YN,'N') = 'Y' OR NVL(Posted_YN,'N') = 'Y')
GROUP BY Menu_Item_Number
ORDER BY Menu_Item_Number;
the result will be:
no rows selected
It's correct since no sale has been made for today yet. But how can I make the query return 0 instead of no rows selected so that I can assign it to the variable?
Are you running the query as shown to test without putting it in a block (using PL/SQL or Toad)? If so, you need to define the variable and structure like this, with a call to NVL() around the SUM() call so V_Today_Sale gets a value if both inputs to SUM() are NULL, and add an exception to catch the NO_DATA_FOUND condition that sets V_Today_Sale to 0 if the where clause conditions are not met:
SET SERVEROUTPUT ON;
DECLARE
V_Today_Sale number := 0;
BEGIN
SELECT NVL(SUM(Selling_Price*Quantity_Sold), 0)
INTO V_Today_Sale
FROM Bill_Item BI, Bill B
WHERE BI.Bill_Number = B.Bill_Number AND
Menu_Item_Number = 1 AND
Bill_Date = sysdate AND
(NVL(Paid_YN,'N') = 'Y' OR NVL(Posted_YN,'N') = 'Y')
GROUP BY Menu_Item_Number
ORDER BY Menu_Item_Number;
EXCEPTION
WHEN NO_DATA_FOUND THEN
V_Today_Sale :=0;
END;
DBMS_OUTPUT.PUT_LINE(V_Today_Sale);

PLSQL Procedure to load data into dimension table from multiple tables

I have a requirement to load distinct costcenternum and a seq_key to be inserted. I wrote a procedure but this is failing one is distinct and even after removing distinct not able to run this procedure.
Please help me to correct this query to generate a seq key and also distinct cost numbers into the division table.
CREATE OR REPLACE
PROCEDURE POPULATE_DIVISION_DIM AS
BEGIN
INSERT INTO DIVISION(
"COST_CENTER_KEY"
,"COST_CENTER_NUM"
,"COST_CENTER_DESC"
,"DIVISION_CODE"
,"DIVISION_DESC"
,"COMPANY_CODE"
,"INSERT_DT"
,"UPDATE_DT"
)
(
SELECT
cc_sequence.nextval cost_center_key
, distinct (pcaf.segment4) costcenter_num
,ffvv.description costcenter_desc
,hoi.org_information9 division
,(SELECT description
FROM hr_lookups
WHERE lookup_type = 'CAT'
AND lookup_code = hoi.org_information9)
division_desc
, ppg.segment1 company
,TRUNC(SYSDATE) insert_dt
,TRUNC(SYSDATE) update_dt
FROM
hr_organization_information hoi
, hr_all_organization_units haou
, pay_cost_allocation_keyflex pcaf
, fnd_flex_values_vl ffvv
, per_all_assignments_f paaf
, pay_people_groups ppg
WHERE 1=1
AND paaf.people_group_id = ppg.people_group_id
AND haou.cost_allocation_keyflex_id =
pcaf.cost_allocation_keyflex_id(+)
AND pcaf.segment4 = ffvv.flex_value(+)
AND (ffvv.FLEX_VALUE_SET_ID is null or ffvv.FLEX_VALUE_SET_ID=
(SELECT FLEX_VALUE_SET_ID FROM FND_FLEX_VALUE_SETS WHERE
FLEX_VALUE_SET_NAME = 'ABCD'))
AND ffvv.enabled_flag(+) = 'Y'
AND haou.organization_id = hoi.organization_id
AND hoi.org_information_context = 'XX'
)
;
COMMIT;
END POPULATE_DIVISION_DIM;

i have several errors of PLS-00049

cursor is there to check for eligibility in student. however i cant even compile the script as i keep getting several of error:
[Error] PLS-00049 (395: 46): PLS-00049: bad bind variable 'SORLCUR_PIDM'.
CURSOR C_ENSP IS
SELECT SFRENSP_ESTS_CODE
,STVESTS_DESC
FROM STVESTS,SFRENSP
WHERE SFRENSP_PIDM = :Sorlcur_PIDM
AND SFRENSP_TERM_CODE = :sorlcur_TERM_CODE
AND SFRENSP_KEY_SEQNO = :SORLCUR_KEY_SEQNO
AND STVESTS_CODE = SFRENSP_ESTS_CODE;
CURSOR C_ENSP_SECOND IS
SELECT 'Y'
FROM SORLCUR, SFRENSP
WHERE SORLCUR_PIDM = :Sorlcur_PIDM
and SORLCUR_PIDM = SFRENSP_PIDM
AND sorlcur_TERM_CODE = :sorlcur_TERM_CODE
AND sorlcur_TERM_CODE = SFRENSP_TERM_CODE
AND SORLCUR_CURRENT_CDE = 'Y'
AND SORLCUR_CACT_CODE = 'ACTIVE'
AND SORLCUR_LMOD_CODE = 'LEARNER'
AND SORLCUR_PRIORITY_NO = 2
AND SFRENSP_KEY_SEQNO = SORLCUR_KEY_SEQNO
AND SFRENSP_ESTS_CODE NOT IN ( 'W', 'X' , 'Z');
v_ENSP_SECOND VARCHAR2(1);
CURSOR c_cohort IS
SELECT chrt.sgrchrt_chrt_code
FROM sgrchrt chrt
WHERE sgrchrt_pidm = :sorlcur_pidm
AND NVL(chrt.sgrchrt_stsp_key_sequence,99999999) = :sorlcur_key_seqno
AND NVL(sgrchrt_term_code_eff,'~') = :stvterm_term_code;
CURSOR c_resd IS
SELECT sgbstdn_resd_code,stvresd_desc
FROM sgbstdn,stvresd
WHERE SGBSTDN_PIDM = :KEY_BLOCK.PIDM
AND SGBSTDN_TERM_CODE_EFF = :KEY_BLOCK.STVTERM_TERM_CODE
AND stvresd_code = sgbstdn_resd_code;
cursor c1 is
select skricas_cas_number,
skricas_cas_status
from skricas a
where a.SKRICAS_PIDM = :key_block.PIDM
and exists (select 'x' from sorlcur
where sorlcur_pidm = skricas_pidm
and sorlcur_seqno = skricas_lcur_seqno
and sorlcur_term_code = :key_block.stvterm_term_code)
and skricas_cas_status = 'USED'
and skricas_cas_exp_date = (select max(a1.skricas_cas_exp_date)
from skricas a1
where a1.skricas_pidm = a.skricas_pidm
and a1.skricas_cas_status = a.skricas_cas_status
);
-- TT06987 start
CURSOR get_JSopt_in IS
SELECT szrasop_opt_in
FROM szrasop
WHERE szrasop_pidm = :sorlcur.Sorlcur_PIDM
AND szrasop_term_code = :sorlcur.Sorlcur_TERM_CODE;
--- v_elig VARCHAR2(1);
CURSOR get_max_szrolps IS
SELECT MAX( SZROLPS_SEQ_NO)
FROM SATURN.SZROLPS
WHERE SZROLPS_PIDM = :sorlcur.Sorlcur_PIDM
AND SZROLPS_TERM_CODE = :sorlcur.Sorlcur_TERM_CODE;
v_max_stage szrolps.szrolps_seq_no%TYPE;
-- TT06987 end
BEGIN
IF :sorlcur_program IS NOT NULL THEN
:SORLCUR_SMRPCMT_TEXT := F_UOG_GET_COMMENT(:sorlcur_program, :sorlcur_term_code, 'PRGTIT');
OPEN C_ENSP;
FETCH C_ENSP INTO :SFRENSP_ESTS_CODE, :ESTS_DESCRIPTION;
CLOSE C_ENSP;
OPEN C_ENSP_SECOND;
FETCH C_ENSP_SECOND INTO v_ENSP_SECOND ;
IF C_ENSP_SECOND%NOTFOUND THEN
:secondary_prog := 'N';
ELSE
:secondary_prog := 'Y';
END IF;
CLOSE C_ENSP_SECOND;
END IF;
OPEN c_cohort;
FETCH c_cohort
INTO :ENTRY_COHORT;
CLOSE c_cohort;
OPEN c_resd;
FETCH c_resd
INTO :sgbstdn_resd_code,:stvresd_desc;
CLOSE c_resd;
SELECT STVATTS_DESC
INTO :mode_desc
FROM STVATTS
WHERE :sorlcur_mode_code = STVATTS.STVATTS_CODE
AND STVATTS.STVATTS_CODE LIKE 'M%';
select stvstyp_desc
into :sorlcur.styp_desc
from stvstyp
where :SORLCUR_STYP_CODE = stvstyp_code;
:sorlcur.SITE_DESC := gb_stvsite.f_get_description(:SORLCUR_SITE_CODE);
get_last_section_completed;
-- added by Mary for 5095
open c1;
fetch c1 into :cas_number,
:cas_status;
close c1;
-- TT06987 start
-- Student eligible??
IF hwzkimag.F_eligible_js (:sorlcur.Sorlcur_PIDM, :sorlcur.sorlcur_TERM_CODE)
THEN
:optin_elig := 'Y';
END IF;
--message(:optin_elig);message(:optin_elig);
IF NVL(:optin_elig,'XXX') = 'Y' THEN
OPEN get_max_szrolps;
FETCH get_max_szrolps
INTO v_max_stage;
CLOSE get_max_szrolps;
-- ELigible and got passed the opt in / opt out stage 7.
IF v_max_stage >= 7 THEN
OPEN get_JSopt_in;
FETCH get_JSopt_in
INTO :optin_yes;
CLOSE get_JSopt_in;
set_item_property('jsopt_message',visible,property_false);
-- Eligible but has not passed opt in / opt out stage 7.
ELSE
:jsopt_message := 'OLR not complete';
set_item_property('jsopt_message',visible,property_true);
END IF;
END IF;
-- TT06987 end
i've solved the problem. There were two errors in the below code. 1st is bad bind variable and 2nd is invalid identifier.
CURSOR C_ENSP IS
SELECT SFRENSP_ESTS_CODE
,STVESTS_DESC
FROM STVESTS,SFRENSP
WHERE SFRENSP_PIDM = :Sorlcur_PIDM
AND SFRENSP_TERM_CODE = :sorlcur_TERM_CODE
AND SFRENSP_KEY_SEQNO = :SORLCUR_KEY_SEQNO
AND STVESTS_CODE = SFRENSP_ESTS_CODE;
1st - i took out the colons on the columns name (e.g. :sorlcur_pidm to just sorlcur_pidm)
2nd - the table name sorlcur wasnt defined as i was calling table columns from 3 different tables.
-- The correct Syntax is below --
CURSOR C_ENSP IS
SELECT SFRENSP_ESTS_CODE
,STVESTS_DESC
FROM STVESTS,SFRENSP,SORLCUR
WHERE SFRENSP_PIDM = Sorlcur_PIDM
AND SFRENSP_TERM_CODE = sorlcur_TERM_CODE
AND SFRENSP_KEY_SEQNO = SORLCUR_KEY_SEQNO
AND STVESTS_CODE = SFRENSP_ESTS_CODE;

Converting an PLSQL select statement into a update

Guys I have such a problem.
I know how to write a good select statement but I have no idea how to turn it into a corresponding update.
Im still learning plsql
Here is my select
select * --count(*)
from POLISY_OT ot
join polisy p on p.poli_id = ot.ot_poli_id
join sou.rai_skl rs on rs.ot_id = ot.ot_id
where ot_under_promil = 0
and ot_skladka_rok <> ot_skladka_netto_rok
and ot_rodzaj_um = 'OP'
and ot_rodzaj = 'D'
and ot_produkt_id = 17
and p.poli_status in ('AK', 'CZ')
and rs.skl_roczna = ot.ot_skladka_rok;
now I would like to wrap it up with an update and create something like this
update (
select * --count(*)
from POLISY_OT ot
join polisy p on p.poli_id = ot.ot_poli_id
join sou.rai_skl rs on rs.ot_id = ot.ot_id
where ot_under_promil = 0
and ot_skladka_rok <> ot_skladka_netto_rok
and ot_rodzaj_um = 'OP'
and ot_rodzaj = 'D'
and ot_produkt_id = 17
and p.poli_status in ('AK', 'CZ')
and rs.skl_roczna = ot.ot_skladka_rok)
set ot_skladka_rok = ot_skladka_netto_rok;
First, I really hope you aren't a student asking for homework help. That really bugs me.
On the assumption it's not, it's a little hard to tell exactly which columns belong to which tables, given that you didn't include the table aliases throughout.
I read this as that you wanted to update a column based on the value in another table, restricting the table updates to records that match a third table).
So I think you want something like this:
UPDATE polisy_ot ot
SET ot_skladka_rok =
(SELECT ot_skladka_netto_rok
FROM sou.rai_skl rs
WHERE rs.ot_id = ot.ot_id
AND rs.skl_roczna = ot.ot_skladka_rok)
WHERE ot_under_promil = 0
AND ot_skladka_rok <> ot_skladka_netto_rok
AND ot_rodzaj_um = 'OP'
AND ot_rodzaj = 'D'
AND ot_produkt_id = 17
AND EXISTS (SELECT NULL
FROM polisy p
WHERE p.poli_id = ot.ot_poli_id
AND p.poli_status IN ('AK', 'CZ'))
Good luck,
Stew

single-row subquery returns more than one row .what should i do in such case

UPDATE STG_ABS_DSD_RECEIPTS_PI_WRK1 A
SET
(
RECEIPT_HEADER_KEY,
ORIG_ACNTNG_EFF_DATE,
GL_DEPT_ID,
RECEIPT_DATE,
RECEIPT_TIME,
TOTAL_INVOICE_COST_HDR,
SUM_EXTENDED_COST_AMT
) =
(SELECT
HDR_RECEIPT_HEADER_KEY,
HDR_ORIG_ACNTNG_EFF_DATE,
HDR_GL_DEPT_ID,
HDR_RECEIPT_DATE,
HDR_RECEIPT_TIME,
HDR_SUM_TOTAL_INVOICE_COST,
PIEDW_EXTENDED_COST_AMT
FROM
STG_ABS_DSD_RECEIPTS_PI_WRK4 B
WHERE
A.SUPPLIER_KEY = B.PIEDW_SUPPLIER_KEY
AND
A.STORE_KEY = B.PIEDW_STORE_KEY
AND
RTRIM(LTRIM(A.SUPPLIER_INVOICE_NBR,0)) = RTRIM(LTRIM(B.PIEDW_SUPPLIER_INVOICE_NBR,0))
AND
TO_DATE(A.PIEDW_INV_TRAN_DATE,'YYYYMMDD') = B.PIEDW_INVOICE_DATE
AND
B.HDR_FOUND_FLAG IN ('N', 'MY'))
WHERE EXISTS
(SELECT 1 FROM STG_ABS_DSD_RECEIPTS_PI_WRK4 B
WHERE
A.SUPPLIER_KEY = B.PIEDW_SUPPLIER_KEY
AND
A.STORE_KEY = B.PIEDW_STORE_KEY
AND
RTRIM(LTRIM(A.SUPPLIER_INVOICE_NBR,0)) = RTRIM(LTRIM(B.PIEDW_SUPPLIER_INVOICE_NBR,0))
AND
TO_DATE(A.PIEDW_INV_TRAN_DATE,'YYYYMMDD') = B.PIEDW_INVOICE_DATE
AND
B.HDR_FOUND_FLAG IN ('N', 'MY'));
You should ensure that the subquery only returns the row that you want by providing the correct joins from the table you are updating, or if you just want one row out of many that might be returned then use "WHERE ROWNUM = 1" (or a LIMIT clause in other RDBMSs or Oracle 12c)

Resources