1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle Database Administration for Microsoft SQL Server DBAs part 28 potx

10 338 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 75,41 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

SQLPLUS> select * from emp; no rows selected SQLPLUS> exec INS_EMP; PL/SQL procedure successfully completed.. SQLPLUS> select * from emp; ## Add commit to stored procedure SQLPLUS> cre

Trang 1

EMP_NAME EMP_DEPT

SQLPLUS> rollback;

Rollback complete.

SQLPLUS> select * from emp;

no rows selected

This example uses an anonymous block of code, rather than a stored procedure If you were to put this statement in a stored procedure, after executing the stored procedure, if you did not have the commits in the stored procedure, you could still roll back after the execution of the procedure

SQLPLUS> create procedure INS_EMP

as

begin

insert into emp values('Mandy',10);

insert into emp values('Emily',20);

savepoint before_delete;

delete from emp where emp_dept=20;

end;

/

Procedure created.

SQLPLUS> select * from emp;

no rows selected

SQLPLUS> exec INS_EMP;

PL/SQL procedure successfully completed.

SQLPLUS> select * from emp;

SQLPLUS> rollback to before_delete;

Rollback complete.

SQLPLUS> select * from emp;

SQLPLUS> commit;

Commit complete.

SQLPLUS> rollback;

Trang 2

Rollback complete.

## Rollback ineffective because commit already done.

SQLPLUS> select * from emp;

## Add commit to stored procedure

SQLPLUS> create or replace procedure INS_EMP

as

begin

insert into emp values('Mandy',10);

insert into emp values('Emily',20);

savepoint before_delete;

delete from emp where emp_dept=20;

commit;

end;

/

Procedure created

SQLPLUS> exec ins_emp;

PL/SQL procedure successfully completed.

SQLPLUS> select * from emp;

## commit part of the stored procedure so rollback

## to a savepoint will error out

SQLPLUS> rollback to before_delete;

rollback to before_delete

*

ERROR at line 1:

ORA-01086: savepoint 'BEFORE_DELETE' never established

As you can see from the examples, in the same session without a

commit, rollbacks are possible to the beginning of the statement or to the

savepoints

Defining Commits

With the transaction savepoints in place, you now need to confirm the

changes and commit them The transaction size is important, as noted

earlier You do not want commits every record; even every 500 can be too

small Locking is less of a concern with commit points in Oracle

Trang 3

If looping through the data that is being processed can be validated, then

a bulk of the updates can be committed or rolled back as a group in the transaction The raising of errors in the procedure will also allow for rollbacks

in the error handling, as discussed later in this chapter

Commits should be put into the code as needed It should not be

expected that executing another procedure will automatically commit, or that a child procedure will commit automatically when completed When changing tables and performing DDL statements with transactions in the same session, a commit does happen before and after the structure change

So, if you did some transactions, and then did an ALTER TABLE or

CREATE INDEX, the changes would be committed

## Example loop to commit every 10000

declare

loop_num number :=0;

cursor c_products is

select item_id from products;

begin

for i in c_products

loop

update products set prod_num = prod_num + 2000 where item_id = i.item_id;

loop_num := loop_num + 1;

if mod(loop_num, 10000) = 0 THEN COMMIT;

end if;

end loop;

commit;

end;

This example can be modified to have a parameter passed in to adjust the commit value, or if it’s part of a package, it can have a global variable defined for the number of rows to commit at a time

Notice that the example loop first gathers the IDs to be updated in a cursor Next, let’s look at cursor processing in Oracle

Cursor Processing

In SQL Server, because of the locking and processing of transactions, bulk transactions are normally the way to go Looping through cursors is not normally the most efficient way to process transactions However, in

Oracle, implicit and explicit cursors are used to process transactions

Trang 4

Implicit cursors are used automatically to process SELECT, UPDATE,

INSERT, and DELETE statements If you want to perform some other action with each row that is being processed, you will need to define an explicit

cursor Explicit cursors can be very useful in handling transactions that

require additional work for the data or for handling the commit point size

NOTE

SELECT INTO, which retrieves one row of

data, also uses an implicit cursor If there is

more than one record returned with the

SELECT INTO, an error is raised for handling

of TOO_MANY_ROWS or NO_DATA_FOUND, as

discussed in the “Error Handling” section later

in this chapter

The Oracle cursor works in a similar manner to a temporary table in SQL Server The cursor pulls out the data set that is to be worked with and uses

that in the rest of the code It’s true that SQL Server also has cursors, which

can be declared and opened, and the next record can be fetched and then

closed But behind the scenes, SQL Server is handling this in a temporary

table With Oracle’s version, we skip to the temporary table And keep in

mind that Oracle may already be using implicit cursors

With a cursor, several attributes are useful in processing the rows:

%NOTFOUND, %FOUND, %ROWCOUNT, and %ISOPEN The %NOTFOUND

attribute is good for error handling of the cursor to check if data is even

returned in the SELECT operation The cursor could be open for processing

as long as new values are found or while the cursor stays open and hasn’t

been explicitly closed

DECLARE

CURSOR c_emp_rec IS

select emp_id, emp_name from emp

where emp_dept = var_in_dept_id;

BEGIN

IF NOT c_emp_rec%ISOPEN

THEN

OPEN c_emp_rec;

END IF;

- Do stuff

.

END;

Trang 5

BULK COLLECTor FOR loops can be used for cursor processing when you have an expected value of the set of results for the cursor or a manageable set of data

DECLARE

TYPE dept_list IS VARRAY of varchar2(50);

v_dept_list dept_list;

BEGIN

select dept_name

BULK COLLECT INTO v_dept_list

from departments;

FOR i IN 1 v_dept_list.COUNT

LOOP

Do stuff with department names END LOOP;

END;

Another cursor type is a REF CURSOR This is a cursor variable that can

be defined with different queries at runtime Instead of just declaring a cursor

as a SELECT statement, a datatype is defined as a REF CURSOR, and then can be associated with a variable The SELECT statement can even be put together in a variable and then be used with the cursor

SQLPLUS> create or replace procedure products_query (

var_prod_id product.prod_id%TYPE,

var_prod_name product.name%TYPE)

IS

prod_refcur SYS_REFCURSOR;

v_prod_id product.prod_id%TYPE;

v_prod_name product.name%TYPE;

BEGIN

v_stmt_sql := 'SELECT prod_id, name from product where ' ||

'prod_id = :productid and prod = :prodname';

OPEN prod_refcur FOR v_stmt_sql USING var_prod_id, var_prod_name; LOOP

FETCH prod_refcur INTO v_prod_id, v_prod_name;

EXIT WHEN prod_refcur%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(v_prod_id || ' ' || v_prod_name); END LOOP;

CLOSE prod_refcur;

END;

/

Trang 6

Procedure created.

## To see the output from DBMS_OUTPUT for example purposes

SQLPLUS> set serveroutput on

SQLPLUS> exec product_query(4,'Product 2');

4 Product 2

PL/SQL procedure successfully completed.

The cursor in the example can be set to another SELECT statement as

long as the cursor was closed first Using a variable to build the SELECT

statement gives you a lot of flexibility in the queries that are in the cursor

For example, in application packages, instead of just outputting the

information, values can be updated or used for comparison

Processing with FORALL

With a PL/SQL FORALL loop, you can collect data and perform insert,

update, or delete operations

## Create sample table of months

SQLPLUS> create table forall_months (

description VARCHAR2(50));

Table created.

## Insert some data for example

SQLPLUS> INSERT INTO forall_months VALUES (1, 'JAN');

1 row created.

SQLPLUS> INSERT INTO forall_months VALUES (2, 'FEB');

1 row created.

SQLPLUS> INSERT INTO forall_months VALUES (3, 'MAR');

1 row created.

.

SQLPLUS> COMMIT;

Commit complete.

## Create procedure that uses FORALL loop to collect

## the data and update it.

SQLPLUS> create or replace procedure update_with_year

AS

TYPE t_forall_months_tab IS TABLE OF forall_months%ROWTYPE;

l_tab t_forall_months_tab;

BEGIN

SELECT *

BULK COLLECT INTO l_tab

FROM forall_months;

Trang 7

FOR indx IN l_tab.first l_tab.last LOOP

l_tab(indx).description := l_tab(indx).description||

' 2010 Information';

END LOOP;

FORALL indx IN l_tab.first l_tab.last

UPDATE forall_months

SET description = l_tab(indx).description

WHERE id = l_tab(indx).id;

COMMIT;

END;

/

Procedure created.

## Execute procedure and look at the data.

SQLPLUS> exec update_with_year;

PL/SQL procedure successfully completed.

SQLPLUS> SELECT * FROM forall_months;

ID DESCRIPTION -

-1 JAN 20 -10 Information

2 FEB 2010 Information

3 MAR 2010 Information

4 APR 2010 Information

5 MAY 2010 Information

6 JUN 2010 Information

7 JUL 2010 Information

8 AUG 2010 Information

9 SEP 2010 Information

10 OCT 2010 Information

11 NOV 2010 Information

12 DEC 2010 Information

12 rows selected.

Functions

A function in Oracle is the same thing as it is in SQL Server: a program to return some value In general, the functions in Oracle are scalar-valued functions They return a value to what called the function In contrast, stored procedures do not return anything Table 9-4 summarizes function types in SQL Server and Oracle

Coding functions is similar to creating procedures Functions can take input parameters and handle errors, but they always return a value Here is

Trang 8

an example of a simple function that takes in some parameters and returns

a value:

SQLPLUS> create or replace function

get_customer_name(var_cust_id in number)

return varchar2

v_cust_name varchar2(40);

as

BEGIN

SELECT cust_name into v_cust_name

from customers where cust_id = var_cust_id;

return v_cust_name;

END;

/

You can write code to modify and manipulate the values as needed or

pull information from other tables

Oracle provides multiple system-defined functions for working with

values, dates, and characters Instead of the SQL Server functions of CAST

and CONVERT, Oracle has TO_ functions: TO_DATE, TO_CHAR, and TO_

NUMBER These allow for formatting and converting a datatype to another

type The following demonstrates some of the system-defined functions

SQLPLUS> select amount from sales

where sales_date >= TO_DATE('05/01/2010','MM/DD/YYYY');

SQLPLUS> select TO_CHAR(sysdate,'YYYYMMDD:HH24:MI') from dual;

20100501:21:23 ## Now a character string

## Add 2 months to a date

SQLPLUS> SQL> select add_months(sysdate,2) from dual;

ADD_MONTH

-14-JUL-10

SQL Server Functions Oracle Functions

System- and user-defined functions System- and user-defined functions

Table-valued functions Pipelined table functions

Scalar-valued functions Functions

TABLE 9-4. Function Types in SQL Server and Oracle

Trang 9

## Find the first occurrence of some characters

SQLPLUS> select INSTR('Michelle','ich') from dual;

INSTR('MICHELLE','ICH')

-2

## Replace character with another

SQLPLUS> select replace('Gig Grown Gear','G','B') from dual;

REPLACE('GIGGR

-Big Brown Bear

## Replace characters and remove spaces

SQLPLUS> select replace(replace('Gig Grown Gear','G','B'),' ','') from dual;

REPLACE(REPL

-BigBrownBear

## Substitute a value for NULLs

SQLPLUS> select sales_state,NLV(amount,0) from sales;

STATE_ID AMOUNT

.

## Handling CASE

SQLPLUS> select UPPER('Michelle'), LOWER('MicHelle') from dual;

Functions can be used to do comparisons or change data As discussed

in Chapter 8, function-based indexes improve performance when using these types of functions to access tables Even user-defined functions can be used in indexes

The pipelined table functions are used to return a collection that can be queried in the same way as a table

## first create the needed types

SQLPLUS> create type emp_row_type as object (

empname varchar2(20),

empid number,

deptid number,

status varchar2(10));

/

Trang 10

Type created.

create type emp_table_type as table of emp;

/

Type created.

SQLPLUS> create or replace function get_all_names (

p_empname in varchar2,

p_empid in number,

p_deptid in number,

p_status varchar2)

RETURN emp_table_type as

v_tab emp_table_type := emp_table_type();

BEGIN

for cur in (select ename,empno,deptno,job from emp2

where hiredate < sysdate - 1)

LOOP

v_tab.extend;

v_tab(v_tab.last) := emp_row_type

(cur.ename,cur.empno,cur.deptno,cur.job);

END LOOP;

return v_tab;

end;

/

Function created.

Oracle Database 11g has a result cache for functions Return values can

be cached to reduce the time needed to get the data out of the function The following shows the basic structure for defining a function to use the result

cache

create or replace function get_product (p_in in NUMBER)

return varchar2

result_cache

as

.

BEGIN

function code

END;

/

The optional clause RELIES_ON will invalidate the cache if the

dependent objects are modified Oracle Database 11g Release 2 uses

RELIES_ONby default, so it will automatically track dependencies and

invalidate the cached results when necessary This way, the cache will

continue to return the correct result set

Ngày đăng: 04/07/2014, 05:20