Got this error when trying to declare a cursor - database

Trying to create cursor for counting the print all the country and got these errors

%rowtyBe?
fetch should be terminated by a semi-colon
when clause doesn't have =
exit clause should immediately follow fetch
So, for sample data
SQL> SELECT * FROM countries;
COUNTRY_ID COUNTRY REGION_ID
---------- ------- ----------
1 Croatia 1
2 Austria 1
3 Germany 2
SQL> SET SERVEROUTPUT ON
that PL/SQL block might look like this:
SQL> DECLARE
2 CURSOR cur_country IS
3 SELECT country_id, country_name, region_id
4 FROM countries
5 WHERE region_id = 1;
6
7 v_ctr_record cur_country%ROWTYPE;
8 BEGIN
9 OPEN cur_country;
10
11 LOOP
12 FETCH cur_country INTO v_ctr_record;
13
14 EXIT WHEN cur_country%NOTFOUND;
15
16 DBMS_OUTPUT.put_line (
17 'Country name '
18 || v_ctr_record.country_name
19 || ' country_id '
20 || v_ctr_record.country_id
21 || ' Region id '
22 || v_ctr_record.region_id);
23 END LOOP;
24
25 CLOSE cur_country;
26 END;
27 /
Country name Croatia country_id 1 Region id 1
Country name Austria country_id 2 Region id 1
PL/SQL procedure successfully completed.
SQL>
Alternatively, switch to a cursor FOR loop; it is simpler to use:
SQL> BEGIN
2 FOR v_ctr_record IN (SELECT country_id, country_name, region_id
3 FROM countries
4 WHERE region_id = 1)
5 LOOP
6 DBMS_OUTPUT.put_line (
7 'Country name '
8 || v_ctr_record.country_name
9 || ' country_id '
10 || v_ctr_record.country_id
11 || ' Region id '
12 || v_ctr_record.region_id);
13 END LOOP;
14 END;
15 /
Country name Croatia country_id 1 Region id 1
Country name Austria country_id 2 Region id 1
PL/SQL procedure successfully completed.
SQL>

Related

Execute select statement within an IF clause Oracle

This is a query from SQL Server, what I want to ask is, how do I want to get the same result in Oracle, what would be the query?
I need result like this: 'this is query on SQL Server'
declare #a int = 6
if #a = 1
begin
select *
from table_A
end
else
begin
select *
from table_B
end
I have tried like this on oracle but failed
declare
type FF_rec is record(
st_Value number
);
var_ff FF_rec;
begin
var_ff.st_Value:=1;
if 1<=0 then
select * from Table_A;
else
select * from Table_B;
end if;
end;
If it has to be at SQL level, then maybe you can use such a code: depending on a value passed to PAR_WHAT substitution variable, you'll get result from EMP or DEPT table.
Because of UNION set operator, select column lists must match in number and datatype,
i.e.
you can't select e.g. two columns from the 1st select and 5 columns from the 2nd;
nor can they not be matched in datatype, e.g. 1st column of 1st select is DATE, while 1st column of 2nd select is NUMBER
So:
SQL> select empno, ename, job
2 from emp
3 where &&par_what = 1
4 union
5 select deptno, dname, loc
6 from dept
7 where &&par_what = 2;
Enter value for par_what: 1
EMPNO ENAME JOB
---------- -------------- -------------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7654 MARTIN SALESMAN
<snip>
14 rows selected.
SQL> undefine par_what
SQL> /
Enter value for par_what: 2
EMPNO ENAME JOB
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
If you're OK with PL/SQL, then one option is to create a function that returns refcursor. Which one? Depends on parameter you pass to it:
SQL> create or replace function f_test (par_what in number)
2 return sys_refcursor
3 is
4 l_rc sys_refcursor;
5 begin
6 if par_what = 1 then
7 open l_rc for select deptno, ename, job, sal, hiredate from emp;
8 elsif par_what = 2 then
9 open l_rc for select deptno, dname, loc from dept;
10 end if;
11
12 return l_rc;
13 end;
14 /
Function created.
Testing:
SQL> select f_test(1) from dual;
F_TEST(1)
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO ENAME JOB SAL HIREDATE
---------- ---------- --------- ---------- ----------
20 SMITH CLERK 800 17.12.1980
30 ALLEN SALESMAN 1600 20.02.1981
30 WARD SALESMAN 1250 22.02.1981
20 JONES MANAGER 2975 02.04.1981
30 MARTIN SALESMAN 1250 28.09.1981
30 BLAKE MANAGER 2850 01.05.1981
<snip>
14 rows selected.
SQL> select f_test(2) from dual;
F_TEST(2)
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>

SQL query to calculate summation of row with previous row along with missing rows

This is my table
Month Year count of subscription per date
---- ---- ----------------------------
1 2010 10
2 2010 30
4 2010 20
7 2010 40
2 2011 60
Please need your help, I need to get the result like below table, summation second row with first row, same thing for another rows: Here some months are missed in above table got added with 0 as count of subscription column
Month Year count of subscription per date sum of subscription
---- --- ---------------------------- ---------------------
1 2010 10 10
2 2010 30 40
3 2010 0 40
4 2010 20 60
5 2010 0 60
6 2010 0 60
7 2010 40 100
8 2010 0 100
9 2010 0 100
10 2010 0 100
11 2010 0 100
12 2010 0 100
1 2011 0 100
2 2011 60 160
3 2011 0 160
and so on till
12 2011 0 160
You can try this way
create table #temp
(
[Month] int,
[year] int,
[count of subscription per date] int,
[sum of] int
)
declare #id int,#sumall int
set #id=1
set #sumall=0
while(#id<=12)
begin
if exists(select month from [your table] where month=#id)
begin
set #sumall=#sumall+(select count from [your table] where month=#id)
insert into #temp
select month,year,count,#sumall as summ from [your table] where month=#id
end
else
begin
insert into #temp
select #id,'2010',0,#sumall
end
set #id=#id+1
end
select * from #temp

How to Group Items in a Count statement

I'm trying to create a query that will return Total Claims reported in 0-3 days, 4-7 days, 8-14 days, and 15+
Select DATEDiff(DD,LossDate,DateReported) As TimeToReport,Count(ClaimId) As Num from LossRun
where PolicyNum='1234567890'
And PolTerm='201403'
Group By DATEDiff(DD,LossDate,DateReported)
order by DATEDiff(DD,LossDate,DateReported);
This is what i get
TimeToReport NumofClaims
0 5
1 3
2 1
3 4
4 3
5 2
6 2
7 2
8 1
12 1
13 1
14 2
15 2
48 1
52 1
107 1
121 1
147 1
533 1
Basically i want to see the total for 0-3, 4-7,8-14,and the rest,,,, timeToReport
You can try to use SUM with CASW WHEN
select
SUM(CASW WHEN TimeToReport <= 3 THEN NumofClaims ELSE 0 END) '0~3 day',
SUM(CASW WHEN TimeToReport >= 4 AND TimeToReport <=7 THEN NumofClaims END) '4-7 days',
SUM(CASW WHEN TimeToReport >= 8 AND TimeToReport <=14 THEN NumofClaims ELSE 0 END) '8-14 days',
SUM(CASW WHEN TimeToReport >= 15 THEN NumofClaims ELSE 0 END) '15+ day'
from (
Select DATEDiff(DD,LossDate,DateReported) As TimeToReport,Count(ClaimId) As Num
from LossRun
where PolicyNum='1234567890'
And PolTerm='201403'
Group By DATEDiff(DD,LossDate,DateReported)
) t
The most simple way is going to be by creating your own temp table which includes the min and max for each bucket and then joining to it.
declare #t table (OrderedID int, EmpID int, EffDate date, Salary money)
insert into #t
values
(1,1234,'20150101',1)
,(2,1234,'20160101',2)
,(3,1234,'20170101',8)
,(4,1234,'20180101',15)
,(1,2351,'20150101',17)
,(5,1234,'20190101',4)
,(5,1234,'20190101',2)
,(5,1234,'20190101',9)
declare #Bin table (MinVal int, MaxVal int)
insert into #Bin
values
(1,3)
,(4,6)
,(7,9)
,(10,15)
,(15,20)
,(20,25)
Select
B.MinVal,count(T.EmpID) as EmpsInBin
From #t T
inner join #Bin B on T.Salary between B.MinVal and B.MaxVal
group by B.MinVal
Output
MinVal EmpsInBin
1 3
4 1
7 2
10 1
15 2

T-SQL query to write case statements with different scenarios

I have 2 tables Test Table and Investigation table.
Test table has
ChildID AddressID TestID TestValue TestDate
1 1 1 20 08/04/2017
2 2 2 20 09/04/2017
2 2 3 10 10/04/2017
When a child has test value >=20 the system automatically generates a Investigation on address but cannot open when between 15 and 19.9
Investigation Table
ChildID InvestID AddressID Status
1 1 1 open
2 2 2 open
If I get a new incoming Test record for child id's this is how my table looks
ChildID AddressID TestID TestValue TestDate
1 1 1 20 08/04/2017
1 5 4 16 12/04/2017(New record)
2 2 2 20 09/04/2017
2 2 3 10 10/04/2017
2 3 5 19 12/04/2017(New Record)
Scenario 1
I want to select New records and show 'status'(new column) as 'New address' case where Test value is between 15 and 19.9 and test date is 90 days apart and address id is not equal for two tests. Don't select any record if the address is same.
Scenario 2
If the child has second testvalue between 15 and 19.9 with same addess id
ChildID AddressID TestID TestValue TestDate
3 6 10 16 08/04/2017
3 6 20 18 11/04/2017 (New Record)
Select the new records with status as 'New Case and New address'
Scenario 3
ChildID AddressID TestID TestValue TestDate
3 6 10 16 08/04/2017
3 6 20 18 11/04/2017
3 7 21 17 02/04/2018 (New record)
Show latest record status as 'new address' because it has different address.
So far I have written the query but I am unable to compare records and write case statements for 'Status column'. I am only able to select records.
Select childid,Testid,TestDate,
TestValue,addressid,lc.caseType,
DateDiff(Day,lead(Test) OVER (Partition by Childid order by TestDate desc),Testdate) as Datediff,
DateDiff(day,First_Value(Testdate) Over (Partition by Childid order by b2.Testdateasc),Testdate) as Datedif1
from Test T
Left Join Investigation I
on T.child=I.childid
and b.observationValue between 15 and 19.99
and Datedif1>=90 or Datediff>=90

unable to group by on multiple column in Pivot sql Query

I am working in a restaurant project. I have 4 table for sale module.
order master.
order details.
itemEntry
waiter_info
They require a report which will show each item sale quantity for each waiter.
MENU_NAME MENU_ID PRICE Total Foisal Kamal Sajib
Naan 2 10.00 8 6 2 0
Parata 1 10.00 10 6 4 0
Vaji 3 30.00 15 8 6 1
My query is below:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Name)
FROM (SELECT DISTINCT Name FROM Waiter_Info) AS Waiter
print #ColumnName
SET #DynamicPivotQuery = N'
SELECT * from vw_ItemWiseSale
pivot
(
sum(QUANTITY) for WAITER in ('+ #ColumnName +')) as pvt'
EXEC sp_executesql #DynamicPivotQuery
My output is:
MENU_NAME MENU_ID PRICE Total Foisal Kamal Sajib
Naan 2 10.00 20 NULL 2 NULL
Naan 2 10.00 60 6 NULL NULL
Parata 1 10.00 40 NULL 4 NULL
Parata 1 10.00 60 6 NULL NULL
Vaji 3 30.00 30 NULL NULL 1
Vaji 3 30.00 180 NULL 6 NULL
Vaji 3 30.00 240 8 NULL NULL
Please help me to get expected output item wise which mentioned in 3 line.(i,e each row for every item)

Resources