Oracle knowledge learning record

ORACLE programming

1. PL/SQL

1.1 what is pl/sql

  • Procedure processing statements are added to sql language processing
--Syntax:
[declare
	--Declare variable
]
begin
	--Logic code
	[exception
      --exception handling  
    ]
end;

1.2 variables

Syntax for declaring variables:

Variable name type (length);

Syntax of variable assignment:

Variable name:=Variable value;

Case:

Declare the variable water tariff unit price, water tariff words, tons and amount.

Assign values to the unit price, number of words and of water charges.

The tonnage is converted according to the number of words of water charge. The rule is that the number of words of water charge is divided by 1000 and rounded to two decimal places.

Calculate amount, amount = unit price * tons.

Output unit price, quantity and amount.

declare
   --Declare variable
   v_waterprice number(10,2);--Unit price of water charge
   v_usenum number;--Water words
   v_usenum2 number(10,2);--Water tonnage
   v_money number(10,2);--amount of money
begin
   --Variable assignment
   v_waterprice:=2.45;
   v_usenum:=8012;
   v_usenum2:=round(v_usenum/1000,2);  
   v_money:=round(v_waterprice*v_usenum2,2);
   --output
   dbms_output.put_line('Unit Price:'||v_waterprice
   ||' number:'||v_usenum2||' amount of money:'||v_money);
end;

Select into assignment:

--Syntax:
select Column name 1,Column name 2 into Variable name 1, variable name 2  from Table name where condition

Note: the result must be one record. Errors will be reported if there are multiple records or no records

--select into 
declare
   --Declare variable
   v_waterprice number(10,2);--Unit price of water charge
   v_usenum number;--Water words
   v_usenum2 number(10,2);--Water tonnage
   v_money number(10,2);--amount of money
begin
   --Variable assignment
   v_waterprice:=3.45;
   --select into assignment
   select t.usenum into v_usenum from t_account t where t.year='2012' and t.month='01' and t.owneruuid='1';
   v_usenum2:=round(v_usenum/1000,2);  
   v_money:=round(v_waterprice*v_usenum2,2);
   --output
   dbms_output.put_line('Unit Price:'||v_waterprice
   ||' number:'||v_usenum2||' amount of money:'||v_money);
end;

1.3 attribute type

1.% type reference type: refers to the field type of a column in a table

--%type Reference type (Table name.Field name%type)
declare
   --Declare variable
   v_waterprice number(10,2);--Unit price of water charge
   v_usenum t_account.usenum%type;--Water words
   v_usenum2 number(10,2);--Water tonnage
   v_money number(10,2);--amount of money
begin
   --Variable assignment
   v_waterprice:=3.45;
   --select into assignment
   select t.usenum into v_usenum from t_account t where t.year='2012' and t.month='01' and t.owneruuid='1';
   v_usenum2:=round(v_usenum/1000,2);  
   v_money:=round(v_waterprice*v_usenum2,2);
   --output
   dbms_output.put_line('Unit Price:'||v_waterprice
   ||' number:'||v_usenum2||' amount of money:'||v_money);
end;

2.% rowtype record type: identifies the row record type of a table

--%rowtype Record type (Table name%rowtype)
declare
   --Declare variable
   v_waterprice number(10,2);--Unit price of water charge
   v_account t_account%rowtype;--Water words
   v_usenum2 number(10,2);--Water tonnage
   v_money number(10,2);--amount of money
begin
   --Variable assignment
   v_waterprice:=3.45;
   --select into assignment
   select * into v_account from t_account t where t.year='2012' and t.month='01' and t.owneruuid='1';
   v_usenum2:=round(v_account.usenum/1000,2);  
   v_money:=round(v_waterprice*v_usenum2,2);
   --output
   dbms_output.put_line('Unit Price:'||v_waterprice
   ||' number:'||v_usenum2||' amount of money:'||v_money);
end;

1.4 abnormality

  • After an exception occurs, the statement will stop execution and control will be transferred to the exception handling part of the PL/SQL block

  • There are two types of exceptions: predefined exceptions and user-defined exceptions

  • Predefined exception - implicitly thrown when the PL/SQL program violates Oracle rules or exceeds system limits

    NO_DATA_FOUND: use select into to return no rows

    TOO_MANY_ROWS: the result set exceeds one row when select into is executed

  • User defined Exceptions - users can define exceptions in the declaration part of the PL/SQL block, and custom exceptions are explicitly raised through the RAISE statement

--Syntax:
exception
 when Exception type then
 Exception handling logic
--abnormal
declare
     --Declare variable
     v_waterprice number(10, 2); --Unit price of water charge
     v_account    t_account%rowtype; --Water words
     v_usenum2    number(10, 2); --Water tonnage
     v_money      number(10, 2); --amount of money
begin
     --Variable assignment
     v_waterprice := 3.45;
     --select into assignment
     select *
       into v_account
       from t_account t
      where t.year = '2012'
        and t.month = '01' and t.owneruuid='1';
     v_usenum2 := round(v_account.usenum / 1000, 2);
     v_money   := round(v_waterprice * v_usenum2, 2);
     --output
     dbms_output.put_line('Unit Price:' || v_waterprice || ' number:' || v_usenum2 ||
                          ' amount of money:' || v_money);
exception
     when too_many_rows then
          dbms_output.put_line('Multiple rows of records were returned');
     when no_data_found then
          dbms_output.put_line('No records found');
end;

1.5 condition judgment

--Syntax 1:
if condition then logic
end if;

--Syntax 2:
if condition then logic
else
 logic
end if;

--Syntax 3:
if condition then logic
elsif condition  then logic
else logic
end if;

Case:

Three levels of water charges are set: 2.45 yuan / ton below 5 tons, 3.45 yuan / ton for 5 tons to 10 tons and 4.45 yuan / ton for more than 10 tons. The stepped water charge is calculated according to the amount of water charge.

--Condition judgment:
--Set three levels of water charges below 5 tons 2.45 element/Tons,
--5 3 tons to 10 tons.45 element/Tons, 
--Part exceeding 10 tons 4.45 ,
--The step water charge is calculated according to the amount of water charge used.
declare
     v_waterprice1 number(10,2);--Unit Price
     v_waterprice2 number(10,2);--Unit Price
     v_waterprice3 number(10,2);--Unit Price
     v_usenum t_account.usenum%type;
     v_usenum2 number(10,2);--ton
     v_money number(10,2);--amount of money
begin
     v_waterprice1:=2.45;
     v_waterprice2:=3.45;
     v_waterprice3:=4.45;
     select a.usenum into v_usenum from t_account a where a.year='2012' and a.month='02' and a.owneruuid='1';
     v_usenum2:=round(v_usenum/1000,2);
     if v_usenum2<=5 then
          v_money:=round(v_usenum2*v_waterprice1,2);
     elsif v_usenum2<=10 then
          v_money:=round((5*v_waterprice1+(v_usenum2-5)*v_waterprice2),2);
     else 
          v_money:=round((5*v_waterprice1+5*v_waterprice2+(v_usenum2-10)*v_waterprice3),2);
     end if;
     dbms_output.put_line('water consumption:'||v_usenum2||' amount of money:'||v_money);
end;

1.6 cycle

1.6.1 unconditional cycle

--Syntax:
loop
--Circular statement
end loop;
--Unconditional cycle
declare 
     v_num number;
begin
     v_num:=1;
     loop
       exit when v_num>100;
       dbms_output.put_line(v_num);
       v_num:=v_num+1;
     end loop;
end;

1.6.2 conditional cycle

--Syntax:
while condition
loop
--Circular statement
end loop;
--Conditional cycle
declare 
     v_num number:=1;
begin
     while v_num<=100
     loop
          dbms_output.put_line(v_num);
          v_num:=v_num+1;
     end loop;
end ;

1.6.3 for cycle

--Syntax:
for variable in Starting value..Termination value
loop
--Circular statement
end loop;
--for loop
begin
     for x in 1 .. 100 
     loop
          dbms_output.put_line(x);
     end loop;
end;

1.7 cursor

1.7.1 what is a cursor

  • Cursor is a data buffer set up by the system for users to store the execution results of SQL statements.
  • We can understand cursors as result sets in PL/SQL

1.7.2 cursor syntax structure and examples

  1. Declare the cursor in the declaration area. The syntax is as follows

    cursor Cursor name is sql sentence;
    
  2. Use cursor syntax

open Cursor name;
loop
	fetch Cursor name into variable;
	exit when Cursor name%notfound;
end loop;
close Cursor name;

Print price list with owner type 1:

--cursor
--Print price list with owner type 1
declare
v_pricetable t_pricetable%rowtype;--Price line object
cursor cur_price is select * from t_pricetable a where a.ownertypeid='1';--Define cursor
begin
     open cur_price;--Open cursor
     loop
          fetch cur_price into v_pricetable;--Extract cursor to variable
          exit when cur_price%notfound;--Exit the loop when the cursor is below the last line
          dbms_output.put_line('Price:'||v_pricetable.price
          ||' Power consumption:' ||v_pricetable.minnum||'-'||v_pricetable.maxnum); 
     end loop;--End cycle
     close cur_price;--Close cursor
end;

1.7.3 cursor with parameters

  • The condition value of the query statement may be determined at run time. For example, the owner type may be determined at run time
--Cursor with parameters
--Print price list with owner type 1
declare
v_pricetable t_pricetable%rowtype;--Price line object
cursor cur_price(v_ownertype t_pricetable.ownertypeid%type) is 
select * from t_pricetable a where a.ownertypeid=v_ownertype;--Define cursor
begin
     open cur_price(1);--Open cursor
     loop
          fetch cur_price into v_pricetable;--Extract cursor to variable
          exit when cur_price%notfound;--Exit the loop when the cursor is below the last line
          dbms_output.put_line('Price:'||v_pricetable.price
          ||' Power consumption:' ||v_pricetable.minnum||'-'||v_pricetable.maxnum); 
     end loop;--End cycle
     close cur_price;--Close cursor
end;

1.7.4 for loop fetching cursor value

for loop fetching cursor value: there is no need to define variables, write open cursors, close cursors, fetch cursors, and control the exit of the loop

-- for Loop fetch cursor value
--Print price list with owner type 1
declare
cursor cur_price(v_ownertype t_pricetable.ownertypeid%type) is 
select * from t_pricetable a where a.ownertypeid=v_ownertype;--Define cursor
begin
     for v_pricetable in cur_price(1)--for Variable name in Cursor name (parameter)
     loop
          dbms_output.put_line('Price:'||v_pricetable.price
          ||' Power consumption:' ||v_pricetable.minnum||'-'||v_pricetable.maxnum); 
     end loop;--End cycle
end;

2. Storage function

  • Storage functions, also known as user-defined functions, can receive one or more parameters, return a result, and write logic using pl/sql.
  • Stored functions are similar to methods in Java.

Storage function:

create [or replace] function Function name
(Parameter name, parameter type, parameter name, parameter type...)
return Result variable data type
is
--Variable declaration section
begin
--Logical part
return result;
[exception]
end;

Case:

--Storage function
--Requirements: create a storage function according to the address ID Query address name.
create or replace function fun_address
(v_addressid number)--The parameter only specifies the type, not the length 
return varchar2
is
    v_name varchar2(30);
begin
     select a.name into v_name from t_address a where a.id=v_addressid;
     return v_name;
end ;

--Test storage function
select fun_address(3) from dual

Query the owner ID, owner name, owner address and owner address using the function we just created.

--Query owner ID,The owner name, owner address and owner address are implemented using the function we just created.
select a.id owner id,a.name Name of owner,fun_address(a.addressid) Employer's address 
from t_owners a ;

3. Stored procedure

3.1 what is a stored procedure

Stored procedure is a named PL/SQL block, which is stored in the database. It is a kind of database object.

Applications can call stored procedures and execute the corresponding logic.

Both stored procedures and stored functions can encapsulate certain business logic and return results. The differences are as follows:

1. There is a return value in the storage function, which must be returned, and there is only one return value; The stored procedure has no return value. You can return multiple values through outgoing parameters.

2. Stored functions can be used directly in select statements, but stored procedures cannot. Most procedures are called by applications.

3. Stored functions generally encapsulate a query result, while stored procedures generally encapsulate a section of transaction code.

--Stored procedure syntax structure
create [or replace] procedure Stored procedure name
(Parameter name, parameter type,...)--The parameter only specifies the type, not the length 
is|as
--Declare variable
begin
--logic
[exception exception handling]
end;

Three modes of process parameters:

  1. IN incoming parameters (default)

  2. OUT outgoing parameter, which is mainly used to return the running result of the program

  3. IN OUT incoming and outgoing parameters

3.2 creating stored procedures without outgoing parameters

--stored procedure
--Create stored procedure without outgoing parameters: add owner information

--Create sequence
create sequence seq_owners
start with 11;
--Create stored procedure
create or replace procedure pro_owners_add
(v_name varchar2,
 v_addressid number,
 v_housenumber varchar2,
 v_watermeter varchar2,
 v_ownertypeid number)
is
begin
    insert into t_owners 
    values(seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_ownertypeid); 
    commit;
end;

--PL/SQL Call stored procedure method 1:
call pro_owners_add('careless',1,222,45353,1);
--PL/SQL Call stored procedure method two:
begin
    pro_owners_add('Ma erha',1,22552,45766,1); 
end;

3.3 creating stored procedures with outgoing parameters

--Demand: add owner information, and the outgoing parameters are those of the new owner ID
create or replace procedure pro_owners_add2
(v_name varchar2,
v_addressid number,
v_housenumber varchar2,
v_watermeter varchar2,
v_ownertypeid number,
v_id out number)
is
begin
    select seq_owners.nextval into v_id from dual;
    insert into t_owners 
    values(v_id,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_ownertypeid); 
end;

--test
declare
  v_id number(30);
begin
  pro_owners_add2('Zhang ha',1,4365676,669,1,v_id);
  dbms_output.put_line('Successfully inserted, ID: '||v_id);
end;

4. Trigger

4.1 what is a trigger

  • Database trigger is a pl/sql program related to tables.

  • Whenever a specific data operation statement (Insert,update,delete) is issued on the specified table, Oracle automatically executes the statement defined in the trigger.

Trigger classification:

Pre trigger (BEFORE)

Post trigger (AFTER)

Syntax for creating triggers:

create [or replace]  trigger  Trigger Name 
BEFORE | AFTER
[UPDATE][[OR] INSERT][[OR] DELETE [OF Listing]]
ON Table name
[FOR EACH ROW][when condition]
declare
begin

end;

FOR EACH ROW is used to mark that this trigger is a row level trigger, as well as a statement level trigger

4.2 pre trigger cases

--Pre trigger
--Demand: after the user enters the cumulative table quantity of this month, the usage quantity of this month will be calculated automatically.
create or replace trigger tri_account1
before
update of num1
on t_account
for each row  
declare
begin
    :new.usenum:=:new.num1-:new.num0; 
end;

4.3 post trigger cases

--Post trigger
--Requirement: when the user modifies the data in the owner information table, record the values before and after modification
--Create log table
create table owners_log(
updatetime date,
owners_id number,
newname varchar2(30),
oldname varchar2(30)
);
--Create post trigger
create or replace trigger tri_owners
after
update of name
on t_owners
for each row
declare
begin
     insert into owners_log values(sysdate,:old.id,:new.name,:old.name);
end;     
--test
select * from owners_log;
update t_owners a set a.name='Zhang Feng' where a.id='17';

5. Comprehensive cases

5.1 prepare PL/SQL, use 12 tons of water, the owner type is 1, and calculate the step water fee.

--to write PL/SQL ,The tonnage of water consumption is 12 tons, the owner type is 1, and the step water fee is calculated. 
declare
     v_usenum number;
     v_money number(10,2);
     v_ownertypeid number;
     cursor cur_price(ownertype varchar2) 
     is 
     select * from  t_pricetable a where a.ownertypeid=ownertype order by a.minnum;
     v_pricetable t_pricetable%rowtype;--Can be omitted
begin
     v_usenum:=12;
     v_ownertypeid:=1;
     v_money:=0;
     for v_pricetable in cur_price(v_ownertypeid)
     loop
          if v_pricetable.maxnum is null or v_usenum <=v_pricetable.maxnum then
              v_money:=v_money+v_pricetable.price*(v_usenum-v_pricetable.minnum);
              exit;
          else 
             v_money:=v_money+v_pricetable.price*(v_pricetable.maxnum-v_pricetable.minnum);    
          end if;   
     end loop;
     dbms_output.put_line('Total water charge amount:'||v_money);
end;

--to write PL/SQL ,The tonnage of water consumption is 12 tons, the owner type is 1, and the step water fee is calculated. 
declare
     v_usenum number;
     v_money number(10,2);
     v_ownertypeid number;
     cursor cur_price(ownertype varchar2) 
     is 
     select * from  t_pricetable a where a.ownertypeid=ownertype;
     v_pricetable t_pricetable%rowtype;
begin
     v_usenum:=12;
     v_ownertypeid:=1;
     v_money:=0;
     open cur_price(v_ownertypeid);
     loop
          fetch cur_price into v_pricetable;
          exit when cur_price%notfound;
          if v_pricetable.maxnum is null or v_usenum <=v_pricetable.maxnum then
              v_money:=v_money+v_pricetable.price*(v_usenum-v_pricetable.minnum);
          else 
             v_money:=v_money+v_pricetable.price*(v_pricetable.maxnum-v_pricetable.minnum);    
          end if;      
     end loop;
     close cur_price;
     dbms_output.put_line('Total water charge amount:'||v_money);  
end;

5.2 comprehensive case of storage function: create a function for calculating step water charge, and the parameters are owner type and tonnage.

--2.Comprehensive case of storage function: create a function for calculating step water charge, with parameters of owner type and tonnage.
create or replace function fn_watermoney
(v_ownertype number,
v_usenum number)
return number
is
cursor cur_price(v_ownertype number) is 
select * from t_pricetable a where a.ownertypeid=v_ownertype order by a.minnum;
v_pricetable t_pricetable%rowtype;
v_money number(10,2);
begin
    v_money:=0;
    for v_pricetable in cur_price(v_ownertype)
    loop      
              if v_pricetable.maxnum is null or v_usenum<=v_pricetable.maxnum then
                   v_money:=v_money+v_pricetable.price*(v_usenum-v_pricetable.minnum);
                   exit;
              else 
                   v_money:=v_money+v_pricetable.price*(v_pricetable.maxnum-v_pricetable.minnum);
              end if;
    end loop;
    return v_money;
end;
--test
select fn_watermoney(1,12) from dual

5.3 trigger comprehensive case: when the user inputs the cumulative amount of this month, the step water charge will be calculated automatically.

--3.Trigger comprehensive case: when the user enters the cumulative amount of this month, the step water charge will be calculated automatically.
create or replace trigger tri_waterprice
before
update of num1
on t_account
for each  row
declare
    v_usenum2 number(10,2);--Tonnage
begin
    :new.usenum:=:new.num1-:new.num0;
    v_usenum2:=round(:new.usenum/1000,2);
    :new.money:=fn_watermoney(:new.ownertype,v_usenum2);
end;

5.4 integrated case of stored procedure

Demand: when adding owner information, add a record in the account at the same time. The year and month are the year and month of the current date, the initial value (num0) is 0, and other field information (region) and t_ The owners table is consistent

--4.Demand: when adding the owner's information, it shall be in the accounting table at the same time( account)Add a record, year and month
--Is the month and year of the current date, initial value( num0)Is 0,Other field information (area) and t_owners Table consistent

create or replace procedure pro_owners_account
(v_name varchar2,
v_addressid number,
v_housenumber varchar2,
v_watermeter varchar2,
v_ownertypeid number,
v_owneruuid out number)
is
v_num0  number;
v_year char(4);--Attention type
v_month char(2);
v_areaid number;
begin
    select seq_owners.nextval into v_owneruuid from dual;
    select ad.areaid into v_areaid from t_address ad where ad.id=v_addressid;
    v_num0:=0;
    v_year:=to_char(sysdate,'yyyy');
    v_month:=to_char(sysdate,'mm');
    insert into t_owners values(v_owneruuid,v_name,v_addressid,v_housenumber,
    v_watermeter,sysdate,v_ownertypeid) ;
    insert into t_account (id,owneruuid,ownertype,areaid,year,month,num0) 
    values(seq_account.nextval,v_owneruuid,v_ownertypeid,v_areaid,v_year,v_month,v_num0);
    commit;
end;

--test
declare
   v_uuid number(10);
begin
    pro_owners_account('Li Da',1,'52342','4556353',1,v_uuid); 
end;

Added by davitz38 on Tue, 02 Nov 2021 18:24:02 +0200