getting total number to specific patients in rdlc report - asp.net

I have made an rdlc report of total number of patients in a day and it works fine. I have the total number of female male patients, but when the report binds it returns a total equal to the number of rows in my data.
For example if I have 20 rows in my report then below when I print the count it returns the count in 20 rows.
How can I get it to be in only 1 row?
This is the query I'm using:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[Test_test_test]-- '2013/08/02'
-- Add the parameters for the stored procedure here
-- Add the parameters for the stored procedure here
(#date VARCHAR(20))
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'new' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS 'new',
( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'old' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS 'old',
----------------------------------------
( CASE
WHEN GENDER_MASTER.NAME1 = 'Female' THEN GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Females',
( CASE
WHEN GENDER_MASTER.NAME1 = 'Male' THEN GENDER_MASTER.NAME1
ELSE NULL
END ) AS 'Males',
-------------------------------------
CONVERT(VARCHAR, PATIENT_REF_MASTER.CREATION_DATE, 105) AS
'creation_Date',
PATIENT_REF_MASTER.SR_NO AS 'sr_No',
PATIENT_MASTER.PAT_FNAME + ' '
+ PATIENT_MASTER.PAT_SNAME AS 'NAME',
DEPT_ID AS
'Dept_ID',
DEPT_MASTER.DEPT_NAME AS
'Dept_Name',
DOC_MASTER.DOC_ID AS
'Doc_Master',
DOC_MASTER.DOC_FNAME + ' '
+ DOC_MASTER.DOC_SNAME AS
'Doc_Name'
,
PATIENT_MASTER.PAT_ADDR
AS 'addr',
GENDER_MASTER.NAME1 AS
'Pat_Sex',
PATIENT_MASTER.AGE AS 'age',
(SELECT Count(PATIENT_REF_MASTER.SR_NO)
FROM PATIENT_REF_MASTER
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date) AS 'count',
(SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 2) AS
'F_count',
(SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 1) AS
'M_count'
FROM PATIENT_REF_MASTER
LEFT JOIN DBO.OLD_NEW_PATIENT
ON DBO.OLD_NEW_PATIENT.CODE = PATIENT_REF_MASTER.OLD_NEW
LEFT JOIN DBO.DEPT_MASTER
ON DEPT_MASTER.DEPT_CODE = PATIENT_REF_MASTER.DEPT_ID
LEFT JOIN PATIENT_MASTER
ON PATIENT_MASTER.PAT_CODE = PATIENT_REF_MASTER.PAT_ID
LEFT JOIN DOC_MASTER
ON DOC_MASTER.DOC_ID = PATIENT_REF_MASTER.DOC_ID
LEFT JOIN GENDER_MASTER
ON GENDER_MASTER.CODE = PATIENT_MASTER.PAT_SEX
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
--MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
ORDER BY PATIENT_REF_MASTER.SR_NO ASC
-- select Dept_Master.Dept_Name as 'Dept_Name',
-- count(Pat_ID) as 'Pat_ID'
--
-- from Patient_Ref_master
--left join dbo.Dept_Master on Dept_Master.Dept_code = Patient_Ref_master.Dept_ID
--where MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
--group by Dept_Master.Dept_Name
END

I think you're trying to do to many things at once ;-)
The heart of your problem lies here:
SELECT Count(PATIENT_MASTER.PAT_SEX)
FROM PATIENT_MASTER
LEFT JOIN PATIENT_REF_MASTER
ON PATIENT_REF_MASTER.PAT_ID =
PATIENT_MASTER.PAT_CODE
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
AND PATIENT_MASTER.PAT_SEX = 1
By using this query within your query, it will return the total in each and every row. This is also why you can get away with writing the query and not using the GROUP BY clause.
I suggest you do all the work in this query with the exception of the count, and then use another query outside of this one for the count.
A secondary problem is that in your query you're requesting several details about each row, but you want it to come back in one row. You have to decide what you want ;).
In order to get just the counts in one row, try something like this:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[Test_test_test]-- '2013/08/02'
-- Add the parameters for the stored procedure here
-- Add the parameters for the stored procedure here
(#date VARCHAR(20))
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT Count(*) count,
Sum(CASE
WHEN FEMALES IS NOT NULL THEN 1
ELSE 0
END) F_Count,
Sum(CASE
WHEN MALES IS NOT NULL THEN 1
ELSE 0
END) M_Count
FROM (SELECT ( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'new' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS
'new',
( CASE
WHEN OLD_NEW_PATIENT.OLD_NEW = 'old' THEN
PATIENT_REF_MASTER.PAT_ID
ELSE NULL
END ) AS
'old',
----------------------------------------
( CASE
WHEN GENDER_MASTER.NAME1 = 'Female' THEN
GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Females',
( CASE
WHEN GENDER_MASTER.NAME1 = 'Male' THEN
GENDER_MASTER.NAME1
ELSE NULL
END ) AS
'Males',
-------------------------------------
CONVERT(VARCHAR, PATIENT_REF_MASTER.CREATION_DATE, 105) AS
'creation_Date',
PATIENT_REF_MASTER.SR_NO AS
'sr_No',
PATIENT_MASTER.PAT_FNAME + ' '
+ PATIENT_MASTER.PAT_SNAME AS
'NAME'
,
DEPT_ID
AS 'Dept_ID',
DEPT_MASTER.DEPT_NAME AS
'Dept_Name',
DOC_MASTER.DOC_ID AS
'Doc_Master',
DOC_MASTER.DOC_FNAME + ' '
+ DOC_MASTER.DOC_SNAME AS
'Doc_Name',
PATIENT_MASTER.PAT_ADDR AS
'addr'
,
GENDER_MASTER.NAME1
AS 'Pat_Sex',
PATIENT_MASTER.AGE AS
'age'
FROM PATIENT_REF_MASTER
LEFT JOIN DBO.OLD_NEW_PATIENT
ON DBO.OLD_NEW_PATIENT.CODE =
PATIENT_REF_MASTER.OLD_NEW
LEFT JOIN DBO.DEPT_MASTER
ON DEPT_MASTER.DEPT_CODE =
PATIENT_REF_MASTER.DEPT_ID
LEFT JOIN PATIENT_MASTER
ON PATIENT_MASTER.PAT_CODE =
PATIENT_REF_MASTER.PAT_ID
LEFT JOIN DOC_MASTER
ON DOC_MASTER.DOC_ID = PATIENT_REF_MASTER.DOC_ID
LEFT JOIN GENDER_MASTER
ON GENDER_MASTER.CODE = PATIENT_MASTER.PAT_SEX
WHERE PATIENT_REF_MASTER.CREATION_DATE = #date
--MONTH(Patient_Ref_master.creation_Date)=#month and Dept_ID=#dept
)T
ORDER BY PATIENT_REF_MASTER.SR_NO ASC
END
I hope this helps, let me know if you need any more info.
Edit
Found a small mistake in the query I posted, the field names should have been FEMALES not FEMALE and MALES not MALE.
I also set up a scaled down example in SQL Fiddle. Take a look and tell me what you think.

Related

Use case statement in where clause conditional to brings data according to user level

I am trying to create a query that brings me data according to user level and user id.
In my query, Level 1 is Administrator and can see everything, but other users can only see their records.
As i wrote this query works only for other users and not for Administrators.
If my LEVEL_TYPE = 1 then get all rows,
elsif my LEVEL_TYPE 1 then get all rows for this USER_ID.
SELECT cl.ID as ID,
cl.FIRST_NAME || ' ' || cl.LAST_NAME as PATIENT,
cl.AGE as AGE,
CASE
when cl.SEX ='M' then 'Άντρας' when cl.SEX ='F' then 'Γυναίκα'
when cl.SEX ='O' then 'Άλλο' when cl.SEX ='C' then 'Ζευγάρι' END as SEX,
sa.SESSION_AREA as SESSION_AREA,
ms.MARITAL_KIND as MARITAL_KIND,
wt.WORK_KIND as WORK_KIND,
ph.PATIENT_PHOTO as PATIENT_PHOTO,
case when cl.ACTIVE = 1 then 'ΕΝΕΡΓΟΣ'
when cl.ACTIVE = 2 then 'ΑΝΕΝΕΡΓΟΣ' end as PATIENT_ACTIVE,
pt.PAYMENT_KIND as PAYMENT_KIND
FROM CLIENTS cl
left join PAYMENT_TYPE pt on pt.ID = cl.PATIENT_TYPE
left join WORK_TYPE wt on wt.ID = cl.WORKING_CONDITION
left join MARITAL_STATUS ms on ms.ID = cl.MARITAL_STATUS
left join SESSIONS_AREA sa on sa.ID = cl.SESSION_AREA
left outer join PHOTOS ph on ph.CLIENTS_ID = cl.ID
inner join USER_PATIENTS up ON up.PATIENT_ID = cl.ID
inner join APP_USERS au on au.ID = up.USER_ID
WHERE (au.LEVEL_TYPE = 1) or
(au.LEVEL_TYPE <> 1 and up.USER_ID = (SELECT au.id
FROM APP_USERS au
WHERE au.APEX_ID = APEX_UTIL.GET_CURRENT_USER_ID))
ORDER BY cl.ACTIVE, cl.FIRST_NAME || ' ' || cl.LAST_NAME

Crafting a Subquery-able UNION ALL based on the results of a query

Data
I have a couple of tables like so:
CREATE TABLE cycles (
`cycle` varchar(6) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`cycle_type` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start` date DEFAULT NULL,
`end` date DEFAULT NULL
);
CREATE TABLE rsvn (
`str` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL
);
INSERT INTO `cycles` (`cycle`, `cycle_type`, `start`, `end`) values
('202013', 'a', '2021-01-04', '2021-01-31'),
('202013', 'b', '2021-01-04', '2021-01-31'),
('202101', 'a', '2021-01-04', '2021-01-31'),
('202101', 'b', '2021-01-04', '2021-01-31'),
('202102', 'a', '2021-02-01', '2021-02-28'),
('202102', 'b', '2021-02-01', '2021-02-28'),
('202103', 'a', '2021-03-01', '2021-03-28'),
('202103', 'b', '2021-03-01', '2021-03-28');
INSERT INTO `rsvn` (str, start_date, end_date) values
('STR01367', '2020-12-07', '2020-06-21'),
('STR00759', '2020-12-07', '2021-04-25'),
('STR01367', '2021-01-04', '2021-09-12'),
('STR01367', '2021-06-21', '2022-02-27');
Desired Results
For any given cycle, I want to count the number of occurrences of str across cycles. So between cycle 2108 - 2108 (one cycle), I see:
str
count
STR01367
1
STR00759
1
And from between 2108 - 2109 (two cycles) I see:
str
count
STR01367
2
STR00759
1
What I've tried
I'm trying to figure out how to dynamically obtain those results. I don't see any options outside a UNION ALL query (one query for each cycles), so I tried writing a PROCEDURE. However, that didn't work because I want to do post-processing on the query results, and I don't believe you can use the results of a PROCEDURE in a CTE or subquery.
My PROCEDURE (works, can't include results in a subquery like SELECT * FROM call count_cycles (?)):
CREATE PROCEDURE `count_cycles`(start_cycle CHAR(6), end_cycle CHAR(6))
BEGIN
SET #cycles := (
SELECT CONCAT('WITH installed_cycles_count AS (',
GROUP_CONCAT(
CONCAT('
SELECT rsvn.str, 1 AS installed_cycles
FROM rsvn
WHERE "', `cy`.`start`, '" BETWEEN rsvn.start_date AND COALESCE(rsvn.end_date, "9999-01-01")
OR "', `cy`.`end`, '" BETWEEN rsvn.start_date AND COALESCE(rsvn.end_date, "9999-01-01")
GROUP BY rsvn.str
'
)
SEPARATOR ' UNION ALL '
),
')
SELECT
store.chain AS "Chain"
,store.division AS "Division"
,dividers_store AS "Store"
,SUM(installed_cycles) AS "Installed Cycles"
FROM installed_cycles_count r
LEFT JOIN store ON store.name = r.dividers_store
GROUP BY dividers_store
ORDER BY chain, division, dividers_store, installed_cycles'
)
FROM cycles `cy`
WHERE `cy`.`cycle_type` = 'Ad Cycle'
AND `cy`.`cycle` >= CONCAT('20', RIGHT(start_cycle, 4))
AND `cy`.`cycle` <= CONCAT('20', RIGHT(end_cycle, 4))
GROUP BY `cy`.`cycle_type`
);
EXECUTE IMMEDIATE #cycles;
END
Alternatively, I attempted to use a recursive query to obtain my results by incrementing my cycle. This gave me the cycles I wanted:
WITH RECURSIVE xyz AS (
SELECT cy.`cycle`, cy.`start`, cy.`end`
FROM cycles cy
WHERE cycle_type = 'Ad Cycle'
AND `cycle` = '202101'
UNION ALL
SELECT cy.`cycle`, cy.`start`, cy.`end`
FROM xyz
JOIN cycles cy
ON cy.`cycle` = increment_cycle(xyz.`cycle`, 1)
AND cy.`cycle_type` = 'Ad Cycle'
WHERE cy.`cycle` <= '202110'
)
SELECT * FROM xyz;
But I can't get it working when I add in the reservations table:
infinite loop?
WITH RECURSIVE xyz AS (
SELECT cy.`cycle`, 'dr.dividers_store', 1 AS installed_cycles
FROM cycles cy
LEFT JOIN rsvn dr
ON cy.`start` BETWEEN dr.start_date AND COALESCE(dr.end_date, "9999-01-01")
OR cy.`end` BETWEEN dr.start_date AND COALESCE(dr.end_date, "9999-01-01")
WHERE cy.`cycle_type` = 'Ad Cycle'
AND cy.`cycle` = '202101'
UNION ALL
SELECT cy.`cycle`, 'dr.dividers_store', 1 AS installed_cycles
FROM xyz
JOIN cycles cy
ON cy.`cycle` = increment_cycle(xyz.`cycle`, 1)
AND cy.`cycle_type` = 'Ad Cycle'
LEFT JOIN rsvn dr
ON cy.`start` BETWEEN dr.start_date AND COALESCE(dr.end_date, "9999-01-01")
OR cy.`end` BETWEEN dr.start_date AND COALESCE(dr.end_date, "9999-01-01")
WHERE cy.`cycle` <= '202102'
)
SELECT * FROM xyz
What options do I have to get the results I need, in such a way that I can use them in a CTE or subquery?
The results I am looking for are easily obtained via a two-stage grouping. Something like this:
WITH sbc AS (
SELECT cy.`cycle`, dr.str, 1 AS 'count'
FROM cycles cy
LEFT JOIN rsvn dr
ON cy.`start` BETWEEN dr.start_date AND dr.end_date
OR cy.`end` BETWEEN dr.start_date AND dr.end_date
WHERE cy.`cycle_type` = 'Ad Cycle'
AND cy.`cycle` BETWEEN '202201' AND '202205'
GROUP BY cy.`cycle`, dr.str
ORDER BY dr.str, cy.`cycle`
)
SELECT `cycle`, str, SUM(`count`) as `count`
FROM sbc
GROUP BY str
The CTE produces one result per rsvn per cycle. Afterwards all that is needed is to group by store and count the number of occurrences.
Besides being simpler, I suspect that this query is faster than the union concept I was stuck on when I asked the question, since among other things the server does not need to perform a union on multiple grouping queries. However, I do not understand how MariaDB optimizes such queries, and while I am curious I don't have the time to run benchmarks to find out.

Is there any way to accomplish this in IBM DB2 enviroment

In DB2 is there a way to basically say:
case when sku (select * from table1 where tb1field = 'SMOMD') then 'True' end
Okay so this is my query so far, I've been going at this for at least a month now so any help would be great.
select tb4.customer, tb4.sku, tb4.qty, tb4.retqty, tb4.stipqty, tb4.lastdate, tb4.firstdate, tb4.stipdate
from(
--Table 4
select tb3.Customer as Customer, tb3.sku as SKU, tb3.qty as Qty, tb3.retqty as RetQty, tb3.stipqty as STIPQty,
case when tb3.lastdate is null then '00/0000' else substr(tb3.lastdate,5,2)||'/'||substr(tb3.lastdate,1,4) end as LastDate,
case when tb3.firstdate is null then '00/0000' else substr(tb3.firstdate,5,2)||'/'||substr(tb3.firstdate,1,4) end as FirstDate,
case when tb3.stipdate is null then '00/0000' else substr(tb3.stipdate,5,2)||'/'||substr(tb3.stipdate,1,4) end as STIPDate
from(
--Table 3
select tb2.Customer as Customer, tb2.SKU as SKU, tb2.Qty as Qty, tb2.RetQty as RetQty, tb2.STIPQty as STIPQty,
max(case when tb2.TranID in ('010','100') then tb2.datenum end) as LastDate,
min(case when tb2.TranID in ('010','100') then tb2.datenum end) as FirstDate,
case when tb2.RC = '4M' then tb2.datenum end as STIPDate
from(
--Table 2
select tb1.Customer as Customer, tb1.SKU as SKU,
sum(case when tb1.TranID in ('010','100') then abs(tb1.OrdNet) else '0' end) as Qty,
sum(case when tb1.TranID = '500' and tb1.rc != '4M' then abs(tb1.OrdNet) else '0' end) as RetQty,
count(case when tb1.rc = '4M' then tb1.sku end) as STIPQty,
tb1.datenum as datenum, tb1.TranID as tranid, tb1.RC as rc
from(
--Table 1
select distinct stkund as Customer, sthptg||space(1)||stmodl||space(1)||stvari||space(1)||stfarb||space(1)||stgroe as SKU,
stvorg as TranID, stggru as RC, stprg09 as PG9, stprg08 as PG8, stperi as datenum, ormne1 as OrdNet
from st_usus.s_stati_pv
join caspdtau.cospf440 on stadrn = jadr40
where trim(stvert) in ('111S','122S')
and sthptg != 'V'
and aktv40 = 'A'
and stprg01 in ('01','04')
and stprg02 = '01'
and stvorg in ('500','010','100')
and stperi >= '20160100'
) as tb1
group by tb1.Customer, tb1.SKU, tb1.datenum, tb1.tranid, tb1.rc
) as tb2
group by tb2.customer, tb2.sku, tb2.qty, tb2.retqty, tb2.stipqty, tb2.tranid, tb2.rc, tb2.datenum
) as tb3
group by tb3.customer, tb3.sku, tb3.qty, tb3.retqty, tb3.stipqty, tb3.lastdate, tb3.firstdate, tb3.stipdate
) as tb4
order by tb4.Customer, tb4.sku
I'm not going to try to decipher exactly what you're trying to do...
Some general advice, rather than using Nested Table Expressions (NTE)
select <..> from (select <...>from mytable)
Consider Common Table Expressions (CTE)
with
table1 as (select <...> from st_usus.s_stati_pv join caspdtau.cospf440 on stadrn = jadr40)
, table2 as (select <...> from table1)
, table3 as (select <...> from table2)
, table4 as (select <....> from table3)
select <...> from table4;
Each CTE (ie. tableX) can refer to a prior CTE or a physical table/view as needed. The final select can refer to one or more CTE's along with one or more physical tables or views.
Nice thing about building with CTE's, is that you can check your results after each step..
with
table1 as (select <...> from st_usus.s_stati_pv join caspdtau.cospf440 on stadrn = jadr40)
select * from table1;

Case statement duplicating rows - teradata

i have the following query and the problem is in the Case statement. It s being used in a Join condition. for some reason is bringing up both alternatives from the case
here s the code
SELECT C.GREGORIAN_MONTH_ID
,C.BUSINESS_PARTY_ID
,C.TOTAL_MONTO
,C.Capitas_Puntuales
,C.CUIT
,nb_apellido
,nb_oficial_actual
,nb_cne_obe
,nb_nodo
,nb_territorio
,cd_area_negocio
FROM (SELECT gregorian_month_id
,business_party_id
,Case when BUSINESS_PARTY_ID in (88888,200) then '9999999999999' else business_party_ident_num end CUIT
,SUM(amt_accum) Total_Monto
,count(*) Capitas_Puntuales
FROM dbsreg.A127932_PARTY_MAIN_PAYROLL_HISTORY
where gregorian_month_id= 201806
group by 1,2,3
) C
LEFT JOIN
(select NU_CUIT, nb_apellido,nb_oficial_actual, nb_cne_obe, nb_nodo, nb_territorio,cd_area_negocio
,(fh_corte/100 + 190000) gregorian_month_id
from dbsreg.a119527_base_info_gerencial
) G
on C.CUIT = G.NU_CUIT
and (case
when C.gregorian_month_id in (G.gregorian_month_id) then C.gregorian_month_id
else C.gregorian_month_id -1
END) = G.gregorian_month_id
ORDER BY C.BUSINESS_PARTY_ID
anyone can tell what s going on there?
You final query returns C.BUSINESS_PARTY_ID which is not transformed by Case. Your case statement also draws on BUSINESS_PARTY_ID. Did you mean to have C.CUIT instead of C.BUSINESS_PARTY_ID in your outer select statement?
long story short, i moved the case withing to a where statement from table C and added a userdefined value for the gregorian:
SELECT C.GREGORIAN_MONTH_ID
,C.BUSINESS_PARTY_ID
,C.TOTAL_MONTO
,C.Capitas_Puntuales
,C.CUIT
,nb_apellido
,nb_oficial_actual
,nb_cne_obe
,nb_nodo
,nb_territorio
,cd_area_negocio
FROM (SELECT gregorian_month_id
,business_party_id
,Case when BUSINESS_PARTY_ID in (88888,200) then '9999999999999' else business_party_ident_num end CUIT
,SUM(amt_accum) Total_Monto
,count(*) Capitas_Puntuales
FROM dbsreg.A127932_PARTY_MAIN_PAYROLL_HISTORY
where gregorian_month_id= ?FECHA_BASE
group by 1,2,3
) C
LEFT JOIN
(select NU_CUIT, nb_apellido,nb_oficial_actual, nb_cne_obe, nb_nodo, nb_territorio,cd_area_negocio
,(fh_corte/100 + 190000) gregorian_month_id
from dbsreg.a119527_base_info_gerencial
where gregorian_month_id = (Case when ?FECHA_BASE = (gregorian_month_id) then gregorian_month_id else gregorian_month_id-1 end )
) G
on C.CUIT = G.NU_CUIT
ORDER BY C.BUSINESS_PARTY_ID

SQL Developer - Bind Variable "prmMediaDate" is Not Declared

I am running the below PL/SQL block in SQL Developer. I am getting the error Bind Variable "prmMediaDate" is Not Declared. Someone please tell what is missing here:
set serveroutput on;
/* RUN the following as a SCRIPT (F5) */
DECLARE
VARIABLE prmMediaDate varchar2(10);
VARIABLE prmSchdDiv varchar2(2);
VARIABLE prmSchdStore varchar2(4);
VARIABLE prmSchdAssoc varchar2(8);
BEGIN
select '07/17/2017' into :prmMediaDate FROM DUAL;
select '91' into :prmSchdDiv FROM DUAL;
select '91916559' into :prmSchdAssoc FROM DUAL;
SELECT
NVL(ODIV,LA.LABORLEV1NM) AS "schd_division"
,NVL(OLOC,LA.LABORLEV4NM) AS "schd_location"
,NVL(OZONE,LA.LABORLEV5NM) AS "schd_dept"
,NVL(O.ORGPATHTXT,LA.LABORLEV1NM||'-'||LA.LABORLEV4NM||'-'||LA.LABORLEV5NM) AS "orgpath_of_shift"
,SA.SHIFTASSIGNID AS "shiftassignid"
,SA.SHIFTCODEID AS "shiftcodeid"
,SA.ENTEREDONDTM AS "assignmnt_add_dtm"
,ST.ENTEREDONDTM AS "assignmnt_edit_dtm"
,CASE WHEN ST.ACTIONTYPEID IS NULL THEN SA.ENTEREDONDTM ELSE ST.ENTEREDONDTM END as "last_action_dt"
,ST.ACTIONTYPEID AS "last_action_cd"
,AT.SHORTNM AS "last_action_descr"
,SA.DELETEDSW AS "deletedsw"
,TRUNC(SA.SHIFTSTARTDATE) AS "shift_start_date"
,TRUNC(SA.SHIFTENDDATE) AS "shift_end_date"
,TO_CHAR(SA.SHIFTSTARTDATE, 'HH24:MI:SS') AS "shift_start_time"
,TO_CHAR(SA.SHIFTENDDATE, 'HH24:MI:SS') AS "shift_end_time"
,CASE SA.SHIFTTYPEID WHEN 1 THEN 'WORK SHIFT' WHEN 2 THEN 'UNAVAIL' WHEN 3 THEN 'HIDE SHFT' WHEN 4 THEN 'SCHD PAYCD EDIT' WHEN 5 THEN 'HIDE WRK SHFT' WHEN 6 THEN 'HIDE UNAVAIL DAY' ELSE 'UNDEFINED' END as "segment"
,NVL(LA.LABORLEV2DSC,'9999') AS "sell_nonsell"
,P.PERSONNUM AS "assoc_nbr"
,SA.ENTEREDONDTM AS "entered_on_dtm"
from PERSON P
JOIN SHIFTASSIGNMNT SA on SA.EMPLOYEEID = P.PERSONID
JOIN COMBHOMEACCT HA on (P.PERSONID = HA.EMPLOYEEID)
LEFT JOIN SHFTSEGORGTRAN SSOT on SSOT.SHIFTASSIGNID = SA.SHIFTASSIGNID
LEFT JOIN ORGX O on O.ORGIDSID = SSOT.ORGIDSID
LEFT JOIN SHFTASGNMNTTRC ST on ST.SHIFTASSIGNID = SA.SHIFTASSIGNID
LEFT JOIN ACTIONTYPE AT on AT.ACTIONTYPEID = ST.ACTIONTYPEID
LEFT JOIN LABORACCT LA on (LA.LABORACCTID = HA.LABORACCTID)
WHERE
TRUNC(SA.SHIFTSTARTDATE) = :prmMediaDate
AND :prmMediaDate BETWEEN HA.EFFECTIVEDTM AND (HA.EXPIRATIONDTM - 1)
AND ((:prmMediaDate BETWEEN O.EFFECTIVEDTM AND (O.EXPIRATIONDTM - 1)) OR (O.EFFECTIVEDTM IS NULL))
AND (SSOT.SEGMENTNUM = 1 OR SSOT.SEGMENTNUM IS NULL)
AND (TRUNC(SSOT.SHIFTSTARTDATE) = :prmMediaDate OR SSOT.SHIFTSTARTDATE IS NULL)
AND SA.DELETEDSW = 0
AND (O.ODIV = :prmSchdDiv OR LA.LABORLEV1NM = :prmSchdDiv)
AND P.PERSONNUM = :prmSchdAssoc;
end;
/
I have tried multiple options like declaring VARIABLE as var, set Scan ON etc.. But it didnt help.
You need to understand that declare is pl/sql and variable is part of sql*plus program commands.
So to successfully execute that code you need to remove DECLARE command.
Set Serveroutput On;
/* RUN the following as a SCRIPT (F5) */
--DECLARE
Variable Prmmediadate Varchar2(10);
Begin
Select '07/17/2017' Into :Prmmediadate From Dual;
End;
/
print :Prmmediadate
PL/SQL procedure successfully completed.
PRMMEDIADATE
--------------------------------------------------------------------------------
07/17/2017

Resources