I'm trying to create a trigger where if the total number of customer reaches 10 then it should raise an error
This is my plsql code:
SQL> CREATE OR REPLACE TRIGGER customer_count_check
2 BEFORE INSERT OR UPDATE ON customer2
3 FOR EACH ROW
4 DECLARE
5 count_customer NUMBER(5);
6 BEGIN
7 SELECT COUNT(*) INTO count_customer FROM customer2
8 WHERE cusid = :new.cusid;
9 IF count_customer > 10 THEN
10 Raise_application_error(-20000,'Maximum customer count:' ||
11 count_customer || 'reached');
12 ENDIF;
13 END;
14 /
and this is the warning I'm getting:
Warning: Trigger created with compilation errors.
SQL> SHOW ERROR;
Errors for TRIGGER CUSTOMER_COUNT_CHECK:
LINE/COL ERROR
-------- -----------------------------------------------------------------
10/4 PLS-00103: Encountered the symbol ";" when expecting one of the
following:
if
I sometimes also wish the error messages would be more clear.
In line 12:
Wrong
ENDIF;
Right:
END IF;
Also the line counting is sometimes not so intuitive. It says 10/4 while it seems to be 12/4. But the first 2 lines are not considered part of the triggers code and so the counting is line 10 column 4.
SQL> CREATE OR REPLACE TRIGGER customer_count_check
2 BEFORE INSERT OR UPDATE ON customer2
3 FOR EACH ROW
4 DECLARE
5 count_customer NUMBER(5);
6 BEGIN
7 SELECT COUNT(*) INTO count_customer FROM customer2
8 WHERE cusid = :new.cusid;
9 IF count_customer > 10 THEN
10 Raise_application_error(-20000,'Maximum customer count:' ||
11 count_customer || 'reached');
12 END IF;
13 END;
14 /
Related
I was trying to use MEMBER OF function but receiving error "PLS-00306: wrong number or types
of arguments in call to 'MEMBER OF'.". Please let me know, how i can use 'MEMBER OF' function
correctly, i want to avoid iteration.
Table: Employee
EMP_ID EMP_NAME EMP_BRANCH
1 Oliver 104
2 Harry 105
3 Jack 105
4 Jacob 103
DECLARE
TYPE emp_name_type IS RECORD(emp_name employee.emp_name%type);
TYPE emp_name_table_type IS TABLE OF emp_name_type;
emp_name_table_type_array emp_name_table_type;
BEGIN
select x.emp_name BULK COLLECT
into emp_name_table_type_array
from (
select e.emp_name, min(e.emp_id) as emp_id
from employee e
where e.emp_branch = 105
group by e.emp_name
) x
order by x.emp_id;
-- receiving output Harry + Jack
FOR i IN emp_name_table_type_array.FIRST .. emp_name_table_type_array.LAST LOOP
dbms_output.put_line(emp_name_table_type_array(i).emp_name);
END LOOP;
-- here i want to implement something like bellow using 'Member OF' function
IF 'Harry' MEMBER OF emp_name_table_type_array THEN
dbms_output.put_line('yes');
ELSE
dbms_output.put_line('no');
END IF;
END;
/
Thank you
You have one type declaration too many (and have to fix the first dbms_output.put_line call because of that).
SQL> DECLARE
2 TYPE emp_name_table_type IS TABLE OF employee.emp_name%type;
3 emp_name_table_type_array emp_name_table_type;
4 BEGIN
5 select x.emp_name BULK COLLECT
6 into emp_name_table_type_array
7 from (
8 select e.emp_name, min(e.emp_id) as emp_id
9 from employee e
10 where e.emp_branch = 105
11 group by e.emp_name
12 ) x
13 order by x.emp_id;
14
15 -- receiving output Harry + Jack
16 FOR i IN emp_name_table_type_array.FIRST .. emp_name_table_type_array.LAST LOOP
17 dbms_output.put_line(emp_name_table_type_array(i));
18 END LOOP;
19
20 -- here i want to implement something like bellow using 'Member OF' function
21 IF 'Harry' MEMBER OF emp_name_table_type_array THEN
22 dbms_output.put_line('yes');
23 ELSE
24 dbms_output.put_line('no');
25 END IF;
26 END;
27 /
Harry
Jack
yes
PL/SQL procedure successfully completed.
SQL>
I have following table:
Id
offset
length
5000
0
5
5001
5
5
5002
10
4
5003
14
4
5010
23
5
5011
28
5
Offset value in each row is based on summation of offset and length of previous row.
As you can see, 6 rows have been deleted between forth and fifth rows and I need to update again offset column based on regular way. My desired output would be as follow:
Id
offset
length
5000
0
5
5001
5
5
5002
10
4
5003
14
4
5010
18
5
5011
23
5
Is there a pure update SQL statement to achieve this in sqlite?
I Appreciate any help.
If your version of SQLite is 3.33.0+ you can use the UPDATE ... FROM... syntax with SUM() window function:
UPDATE tablename AS t1
SET offset = t2.offset
FROM (
SELECT Id, SUM(length) OVER (ORDER BY Id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) offset
FROM tablename
) AS t2
WHERE t2.Id = t1.Id AND t2.offset IS NOT NULL;
See the demo.
For previous versions use a correlated subquery:
UPDATE tablename AS t1
SET offset = COALESCE(
(SELECT SUM(t2.length) FROM tablename t2 WHERE t2.Id < t1.Id),
t1.offset
);
See the demo.
i just started with pl/sql and found this error. can someone tell what the problem is.
create or replace procedure findmin(x in number, y in number, z out
number)
is
begin
if x<y then z:= x;
else z:=y;
end if;
end;
set serveroutput on;
declare
a number;
b number;
c number;
begin
a:=23;
b:=46;
findmin(a, b, c);
dbms_output.put_line('minimum of the 2 numbers is' || c);
end;
There is NO error. Might be you re not executing it correctly.
SQL> CREATE OR REPLACE PROCEDURE findmin(
2 x IN NUMBER,
3 y IN NUMBER,
4 z OUT NUMBER)
5 IS
6 BEGIN
7
8 IF x<y THEN
9 z:= x;
10
11 ELSE
12 z:=y;
13
14 END IF;
15
16 END;
17
18 /
Procedure created.
SQL> set serveroutput on;
SQL> DECLARE
2 a NUMBER;
3 b NUMBER;
4 c NUMBER;
5 BEGIN
6 a:=23;
7 b:=46;
8 findmin(a, b, c);
9 dbms_output.put_line('minimum of the 2 numbers is ' || c);
10
11 END;
12 /
minimum of the 2 numbers is 23
PL/SQL procedure successfully completed.
In google BigQuery I have done a simple query to get how many music someone has listened.
What I need is to make a sum for all rows returned from the query below (some type of subquery)?
select count(1) cnt
from OF7.PETERV_TEST
where gender='F'
group by userId
Row f0_
1 14
2 1
3 7
4 18
5 1
6 4
7 2
8 2
expected result:
49
you can use:
SELECT sum(cnt)
FROM
(SELECT count(1) cnt
FROM OF7.PETERV_TEST
WHERE gender='F'
GROUP BY userId )
I am hoping to get some help on a view which needs to be pivoted, I am not sure though.
View is in following format:
CASE CASE_ORDER MANAGER MONTHLY_CASES FISCAL_CASES
case_1 1 John 15 84
case_1 1 Jeff 10 80
case_2 2 John 20 90
case_2 2 Jeff 13 65
case_3 3 John 7 72
case_3 3 Jeff 17 70
My final chart should look like the following:
CASE CASE_ORDER JOHN_CURR_MONTH JOHN_FY JOHN_CURR_MONTH JOHN_FY
case_1 1 15 84 10 80
case_2 2 20 90 13 65
case_3 3 7 72 17 70
My problem is that managers can change and so does the number of managers from month to month,
so I can't hard code their names (ie. 'mgr1' and 'mgr2') and use DECODE. It has to be dynamic...
Thanks for your suggestion, I figured it out. In fact there is a similar answer in tom kyte's blog (http://www.oracle.com/technetwork/issue-archive/2012/12-jul/o42asktom-1653097.html) which I modified for my purpose. Here it is:
CREATE OR REPLACE PROCEDURE dynamic_pivot_proc ( p_cursor IN OUT SYS_REFCURSOR )
AS
l_query LONG := 'SELECT case_order, case';
BEGIN
FOR x IN (SELECT DISTINCT manager FROM test_table ORDER BY 1 )
LOOP
l_query := l_query ||
REPLACE( q'|, MAX(DECODE(manager,'$X$',monthly_total)) $X$_current_month|',
'$X$', dbms_assert.simple_sql_name(x.manager) ) ||
REPLACE( q'|, MAX(DECODE(manager,'$X$',fiscal_total)) $X$_fy|',
'$X$', dbms_assert.simple_sql_name(x.manager) );
END LOOP;
l_query := l_query || ' FROM test_table
GROUP BY case_order, case
ORDER BY case_order ';
OPEN p_cursor FOR l_query;
END;
SQL> variable x refcursor;
SQL> exec dynamic_pivot_proc( :x );
SQL> print x
CASE CASE_ORDER JEFF_CURRENT_MONTH JEFF_FY JOHN_CURRENT_MONTH JOHN_FY
1 case_1 10 80 15 84
2 case_2 13 65 20 90
3 case_3 17 70 7 72
Now the thing is instead of printing the result I want to store it in a view. How do I achieve that? I tried to modify the line
l_query LONG := 'SELECT case_order, case';
with
l_query LONG := 'CREATE OR REPLACE VIEW SELECT case_order, case';
Needless to say that it did not work because CREATE OR REPLACE is a DDL statement, so some how I have to use EXECUTE IMMEDIATE.
Any suggestion? Thanks in advance.