zoukankan      html  css  js  c++  java
  • sql, plsql 总结

      1 /*
      2  *====================================== basic sql ==========================================
      3  */
      4  
      5 -- Merge --
      6 merge into copy_emp as ac
      7 using employees e
      8 on (c.employee_id = employee_id)
      9 when matched then
     10     update set
     11     c.first_name = e.first_name
     12     c.last_name = e.last_name
     13     c.department_id = e.department_id
     14 when not matched then
     15     insert values(e.employee_id, e.first_name, e.last_name, e.department_id)
     16 
     17 -- alter table --
     18 alter table dep80
     19 add(job_id varchar(8))
     20 
     21 alter table dep80
     22 modify(job_id varchar(30))
     23 
     24 alter table dep80
     25 drop(job_id)
     26 
     27 alter table dep80
     28 set unused(job_id)
     29 
     30 -- reaname --
     31 rename dept to detail_dept
     32 
     33 -- truncate --
     34 truncat table detial_dept
     35 
     36 -- comment --
     37 comment on table dept IS 'department information'
     38 comment on dept.deptno IS 'department number'
     39 
     40 -- constraint , not null, unique, primary key, foreign key, check --
     41 create table employees (
     42     employee_id        NUMBER(6),
     43     job_id            VARCHAR2(10) NOT NULL,
     44     
     45     constraint emp_id_pk PRIMARY KEY(employee_id)
     46 )
     47 
     48 alter table employees
     49     add constraint emp_manager_fk FOREIGN KEY(manager_id)
     50     REFERENCES employee(employee_id)
     51 
     52 alter table employees
     53     drop constraint emp_manager_fk [cascade]
     54 
     55 alter table employees
     56     disable constraint emp_manager_fk[cascade]
     57 
     58 alter table employees
     59     enable constraint emp_manager_fk
     60 
     61 alter table employees
     62     drop (column1, column2) [cascade constraints]
     63 
     64 -- view --
     65 create or replace view emp_view as select deptno, dname, loc from dept
     66 drop view emp_view
     67 
     68 -- sequence --
     69 create sequence seq_emp
     70 increment by 1
     71 start with 0
     72 maxvalue 20000000
     73 minvalue 0
     74 nocycle
     75 nocache
     76 
     77 -- index --
     78 create index ind_emp on dept(deptno, dname)
     79 
     80 -- synonym --
     81 create public synonym dept for scott.dept
     82 -- 2种方法: 例如 object 在 hr 下, scott 想要访问 hr 下的 table department.
     83 -- 1. 在 scott 模式下, create synonym department for hr.department
     84 -- 2. 在 hr 模式下, create synonym scott.department for department , 注意这种含义是 hr 用户代替 scott
     85 -- 用户在 scott 模式下创建了别名, scott.department 这个表示是在 scott模式下, 所以在 scott 模式下就直接
     86 -- 有了这样一个别名.
     87 
     88 -- create user --
     89 create user leon_master identified by leon
     90 alter user leon_master identified by master ( 修改密码 )
     91 
     92 -- grant privilege --
     93 grant dba to leon_master
     94 grant create session, create table, create sequence to scott ( to role )
     95 grant manager(role) to leon_master
     96 grant update(deptname, location_id) on departments to scott, manager
     97 
     98 -- role --
     99 create role manager;
    100 grant create session, create table, create sequence to manager;
    101 
    102 -- revoke --
    103 revoke create session from scott
    104 revoke update(deptname, location_id) on department from scott, manager
    105 
    106 -- database link --
    107 create public database link mes20
    108 connect to <被链接数据库用户名> identified by <被链接数据库密码>
    109 using 'ASDF'
    110 
    111 /*
    112 tnsnames >>>
    113 ASDF, ASDF2 =
    114   (DESCRIPTION =
    115     (ADDRESS = (PROTOCOL = TCP)(HOST = 109.106.13.25)(PORT = 1521))
    116     (ADDRESS = (PROTOCOL = TCP)(HOST = 109.106.13.22)(PORT = 1521))
    117     (ADDRESS = (PROTOCOL = TCP)(HOST = 109.106.13.26)(PORT = 1521))
    118     (CONNECT_DATA =
    119       (SERVER = DEDICATED)
    120       (SERVICE_NAME = ASDF)
    121     )
    122   )
    123 */
    124 -- relation sub query --
    125 select column1, column2
    126 FORM table1 outer
    127 where column1 operator ( select column1 from table2 where expr1 = outer.exp2);
    128 
    129 select column1, column2
    130 from table1 outer
    131 where exists ( select column1 from table2 where expr1 = outer.exp2);
    132 
    133 update table1 als_1
    134 set column = ( select expression from table2 als_2 where als_1.column = als_2.column);
    135 
    136 delete from table1 als_1
    137 where column operator ( select expression from table2 als_2 where als_1.column = als_2.column);
    138 
    139 -- Hierarchical retrieve --
    140 
    141 select substr(sys_connect_by_path(ENAME,'->'), 3) EMPLOYEE from EMP
    142 connect by prior EMPNO = MGR
    143 start with ename = '小董'
    144 
    145 -- 首先这个查询有一个 connect by prior EMPNO=MGR, 这是一个连接条件, 从 start with 开始找到第一行数据,
    146 -- 然后根据连接条件来进行. 向后遍历. 翻译过来就是, 先从小董开始, 然后小董的 empno 作为父层次 = manager
    147 -- 向后依次遍历.
    148 
    149 /*
    150  * =========================================== plsql =========================================
    151  */
    152  
    153 -- 系统绑定变量 可以直接在 sqlplus 环境中定义
    154 variable g_salary NUMBER 
    155 -- 注意此变量不同于一般意义的plsql变量, 这个是在环境中定义的类似环境变量
    156 
    157 -- PL/SQL 定义变量
    158 declare    v_depno number(2) not null := 100;
    159 declare c_comn constant number := 1400;
    160 declare v_location varchar(20) := 'hello world';
    161 declare v_name employees.lastname%TYPE;
    162 declare v_balance number(10,2);
    163 declare v_min_balance v_balance%TYPE :=10; -- 参照上一个定义 v_balance
    164 -- declare v_home = q'[tom's home]' -- 注意是以双引号内的形式, 实际环境中, 不需要双引号
    165 declare l_right_now DATE NOT NULL DEFAULT SYSDATE;
    166 
    167 
    168 -- 在 PL/SQL 中 sql 部分不需要冒号 :
    169 declare v_bonus NUMBER(6);
    170 begin
    171     select salary * 0.01
    172     INTO v_bouns
    173     FROM employees
    174     WHERE emp_id = '200912';
    175 end;
    176 
    177 -- 游标 --
    178 declare cursor cursor_name IS
    179     select_statement;
    180 open cursor_name
    181 fetch cursor_name into variable1, varibal2
    182 close cursor_name 
    183 -- 以上4步骤, 分别为定义游标, 打开游标, 取出游标, 关闭游标
    184 
    185 -- 游标属性 --
    186 cursor_name%isopen
    187 cursor_name%notfound
    188 cursor_name%found
    189 cursor_name%rowcount
    190 
    191 -- 隐式游标举例 --
    192 Function book_title (isbn_in IN books.isbn%TYPE)
    193 return books.title%type
    194 IS
    195     return_value    book.title%type;
    196 BEGIN
    197     SELECT     title
    198     into    return_value
    199     from    books
    200    where    isbn = isbn_in;
    201    
    202     return    return_value;
    203     
    204     exception
    205         when no_date_found
    206         then
    207             return null;
    208         when too_many_rows
    209         then
    210             errpkg.record_and_stop ('Data integrity error for:' || isbn_in);
    211             raise;        
    212 END;
    213 
    214 -- 显示游标举例 --
    215 Function jealousy_level (
    216     NAME_IN    IN    friends.NAME%TYPE)    RETURN    NUMBER
    217 AS
    218     cursor jealousy_cur
    219     IS
    220         select location from friends
    221         where name = UPPER(name_in);
    222         
    223     jealousy_rec    jealousy_cur%ROWTYPE;    
    224     retval    NUMBER;
    225 BEGIN
    226     OPEN jealousy_cur;
    227     
    228     fetch jealousy_cur into    jealousy_rec;
    229     
    230     IF jealousy_cur%found then
    231         if jealousy_rec.location = 'PUERTO RICO' THEN
    232             retval := 10;
    233         elsif jealousy_rec.location = 'CHICAGO' THEN
    234             retval := 1;
    235         end if;
    236     end if;
    237     
    238     close jealousy_cur;
    239     
    240     return retval;
    241 EXCEPTION
    242     when others then
    243         if jealousy_cur%isopen then
    244             close jealousy_cur;
    245         end if;            
    246 END;
    247 
    248 -- 游标变量 --
    249 TYPE cursor_type_name IS REF CURSOR [RETURN return type];
    250 
    251 TYPE company_curtype IS REF CURSOR RETURN company%ROWTYPE;  -- 强类型
    252 
    253 TYPE generic_curtype IS REF CURSOR;                            -- 弱类型
    254 
    255 -- 从 oracle 9i 开始, 数据库已经替我们定义好了一个弱类型, 直接用就可以了
    256 declare my_cursor SYS_RECURSOR;
    257 
    258 -- 声明游标变量的方法
    259 cursor_name cursor_type_name;
    260 
    261 -- 打开游标变量
    262 open cursor_name FOR select_statement;
    263 -- 从游标变量获取数据, 同静态游标一样
    264 FETCH cursor_variable_name INTO record_name;
    265 FETCH cursor_variable_name INTO varibale_name, variable_name...;
    266     
    267 
    268 -- 游标表达式
    269 CURSOR( subquery )    
    270     
    271 -- 参数化 游标 --  参数的类型只能是 in 类型
    272 declare
    273     v_department    classes.department%type;
    274     v_course        classes.course%type;
    275     
    276     cursor    c_classes is
    277     select * from classes
    278     where department = v_department
    279     and course = v_course;
    280 
    281 declare
    282     cursor c_classes(p_department classes.department%type, p_course classes.course%type) is
    283     select * from classes
    284     where department = v_department
    285     and course = v_course;
    286 open c_classes('HIS', 101);
    287 
    288 -- 游标中的 for update 语句, 加锁, 默认的游标是不会加锁的 --
    289 -- 如果此时该表已经被加锁, 那么这个游标将无限期的被挂起, 直到该表所已经解开, 而 NOWAIT 语句表示不等挂起
    290 -- 如果发现这个表已经被加锁, 直接会提示一个错误, 个人感觉 NOWAIT 好一点
    291 
    292 declare
    293     v_NumCredits    classes.num_credites%type;
    294     
    295     cursor c_RegisteredStudents IS
    296     select * from students
    297     where id in ( select student_id
    298                     from registered_students
    299                     where department = ’HIS‘
    300                     and course = 101)
    301     for update of current_credits;  -- one column
    302     
    303 begin
    304     for v_studentInfo in c_RegisteredStudents
    305     loop
    306         select num_credits
    307         into v_NumCredits
    308         from classes
    309         where department = 'HIS'
    310         and course = 101;
    311         
    312         update students
    313             set current_credits = current_credits + v_NumCredits
    314             where current of c_RegisteredStudents  -- 修改当前行的 column 值
    315     end loop;
    316 end;
    317 
    318 -- 注意 commit; 操作会释放锁, 所以如果你将 commit 写在 for 循环里的话, 那么再没有完成的情况下就释放锁,
    319 -- 会出现错误提示 ORA-1002: fetch out of sequence
    320 
    321 declare
    322     cursor c_AllStudents IS
    323     select * from students
    324     for update;        -- 注意, 这只有 for update, 所以所有的列都被加锁
    325     
    326     v_StudentInfo    c_AllStudents%ROWTYPE;
    327 begin
    328     open    c_AllStudents;
    329     FETCH c_allStudents INTO v_StudentInfo;
    330     -- 如果这时候使用 commit; 那么后边的记录就没有办法进行了, 所以推荐 close cursor 以后再 commit;
    331 end;
    332 
    333 -- 当然, 如果你非想在 for 循环里使用 commit, 做法是, 现将游标全部提取出来, 然后通过 for 循环进行修改
    334 declare
    335     v_NumCredits    classes.num_credites%type;
    336     
    337     cursor c_RegisteredStudents IS
    338     select * from students
    339     where id in ( select student_id
    340                     from registered_students
    341                     where department = ’HIS‘
    342                     and course = 101)
    343     for update of current_credits;  -- one column
    344     
    345 begin
    346     for v_studentInfo in c_RegisteredStudents
    347     loop
    348         select num_credits
    349         into v_NumCredits
    350         from classes
    351         where department = 'HIS'
    352         and course = 101;
    353         
    354         update students
    355             set current_credits = current_credits + v_NumCredits
    356             where current of c_RegisteredStudents  -- 修改当前行的 column 值
    357         commit;  -- 注意此时已经通过 for 循环将所有游标提取到 v_studentInfo里, 并且不能使用
    358                  -- where current of
    359     end loop;
    360 end;
    361 
    362 -- If statement --
    363 IF salary >= 10000 AND salary <=20000
    364 THEN
    365     give_bonus(employee_id, 1500);
    366 ELSIF salary > 20000 AND salary <= 40000
    367 THEN
    368     give_bonus(employee_id, 10000);
    369 ELSIF salary > 40000
    370 THEN
    371     give_bouns(employee_id, 400);
    372 END IF;
    373 
    374 -- case statement --
    375 CASE employee_type
    376 WHEN 'S' THEN
    377     award_salary_bonus(employee_id);
    378 WHEN 'H' THEN
    379     award_hourly_bonus(employee_id);
    380 WHEN 'C' THEN
    381     award_commissioned_bonus(employee_id);
    382 ELSE
    383     RAISE invalid_employee_type;
    384 END CASE;
    385 
    386 CASE TRUE
    387 WHEN salary >= 10000 AND salary <= 20000 THEN
    388     give_bouns(employee_id, 1500);
    389 WHEN salary > 20000 AND salary < 40000 THEN
    390     give_bouns(employee_id, 1000);
    391 ELSE
    392     give_bouns(employee_id, 0);
    393 END CASE;
    394 
    395 -- loop --
    396 
    397 -- basic loop --
    398 PROCEDURE display_multiple_years (
    399     start_year_in IN PLS_INTEGER,
    400     end_year_in IN PLS_INTEGER
    401 )
    402 IS
    403     l_current_year PLS_INTEGER := start_year_in;
    404 BEGIN
    405     LOOP
    406         EXIT WHEN l_current_year > end_year_in;
    407         display_total_sales(l_current_year);
    408         l_current_year := l_current_year + 1;
    409     END LOOP;
    410 END display_muliple_years;
    411 
    412 -- for loop --
    413 procedure display_multiple_years( start_year_in IN PLS_INTEGER, end_year_in IN PLS_INTEGER)
    414 IS
    415 BEGIN
    416     FOR l_current_year IN start_year_in .. end_year_in
    417     LOOP
    418         display_total_sales(l_current_year);
    419     END LOOP;
    420 END display_multiple_years;
    421 
    422 procedure display_multiple_years( start_year_in IN PLS_INTEGER, end_year_in IN PLS_INTEGER)
    423 IS
    424 BEGIN
    425     FOR l_current_year IN (
    426         select * from sales_date
    427         where year between start_year_in and end_year_in)
    428     LOOP
    429         display_total_sales(l_current_year);
    430     END LOOP;
    431 END display_multiple_years;
    432 
    433 -- 游标参考 for loop --
    434 
    435 -- 一般形式的游标 --
    436 declare 
    437     cursor occupancy_cur IS
    438     select pet_id, room_number
    439     from occupancy where occupid_dt = trunc(sysdate);
    440     
    441     occupancy_rec occupancy_cur%rowtype;
    442     
    443 begin
    444     open occupancy_cur;
    445     loop
    446         fetch occupancy_cur into occupancy_rec;
    447         exit when occupancy_cur%notfound;
    448         update_bill(occupancy_rec.pet_id, occupancy_rec.room_id);
    449     end loop;
    450     close occupancy_cur;
    451 end;
    452 
    453 -- For loop 形式游标 --
    454 declare 
    455     cursor occupancy_cur IS
    456     select pet_id, room_number
    457     from occupancy where occupid_dt = trunc(sysdate);
    458 begin
    459     for occupancy_rac in occupacy_cur        -- occupancy 不用定义
    460     loop
    461         update_bill(occupancy_rec.pet_id, occupancy_rec.room_id);
    462     end loop;
    463 end;
    464 
    465 -- while loop --
    466 procedure display_multiple_years( start_year_in IN PLS_INTEGER, end_year_in IN PLS_INTEGER)
    467 IS
    468     l_current_year PLS_INTEGER := start_year_in;
    469 BEGIN
    470     while (l_current_year <= end_year_in)
    471     LOOP
    472         display_total_sales(l_current_year);
    473         l_current_year := l_current_year + 1;
    474     END LOOP;
    475 END display_multiple_years;
    476 
    477 -- --------------------------Exception ------------------------------------------------------------
    478 -- EXCEPTION --
    479 -- 1.抛出异常, 用户错误, 系统错误, 内存泄露等等问题都会抛出异常
    480 --   抛出方式, raise exception_name, raise package_name.exception_name, raise;
    481 --     raise_application_error 也可以抛出异常, 并且可以写自己bussiness的逻辑信息
    482 procedure raise_by_language(code_in IN PLS_INTEGER)
    483 IS
    484     l_message error_table.error_string%TYPE;
    485 BEGIN
    486         SELECT error_string
    487         INTO    l_message
    488         FROM    error_table
    489         where    error_number = code_in
    490         and     string_language = USERNV('LANG');
    491         
    492         RAISE_APPLICATION_ERROR(code_in, l_message);    -- 抛出异常
    493 END;
    494 -- 2. 捕获异常
    495 --      异常种类, oracle定义好有名字的异常, 一共20个, 没名字的异常, 还有就是用户定义异常
    496 --      捕获异常后, 程序不会返回到抛出异常处, 执行完捕获异常, 看是向下还是停止.
    497 --       当处理没有命名的异常时, 可以通过以下语句来定义名称
    498 declare
    499     e_emps_remaining    EXCEPTION
    500     PRAGMA    EXCEPTION_INIT(e_emps_remaining, -2292);
    501 begin
    502     -- do something
    503     exception
    504         when e_emps_remaining then
    505             statement1
    506 end;
    507 -- 3. 内置函数
    508 SQLCODE -- 返回一个错误代码, 如果没有错误, 返回 0
    509 SQLERRM -- 返回错误代码对应的官方错误信息
    510 DBMS_UTILITY.FORMAT_ERROR_BACKTRACK -- 10g 以后开始饮用, 返回一个格式化文本串(可以返回抛出异常行号)
    511 -- ---------------------------------End Exception -------------------------------------------------
    512 
    513 -- --------------------- 动态 sql -----------------------------------------------------------------
    514 
    515 
    516 
    517 -- ---------------------- End 动态 sql ------------------------------------------------------------
    518 
    519     
  • 相关阅读:
    Flink window机制
    用上帝视角来看待组件的设计模式
    npm和package.json那些不为常人所知的小秘密
    四步走查智能硬件异常Case
    PorterDuffXfermode 图像混合技术在漫画APP中的应用
    发布流程进化史
    新手入门Sqlalchemy
    OpenResty 最佳实践 (2)
    更新数据库触发器
    删除约束名字段名
  • 原文地址:https://www.cnblogs.com/moveofgod/p/3456183.html
Copyright © 2011-2022 走看看