Oracle Multi-Table Association UPDATE statement

Source: Internet
Author: User
Tags aliases

Oracle Multi-Table Association UPDATE statement 2013-12-23 17:15:49

Category: Oracle

For the sake of convenience, the following simple models are established and some test data are constructed:
In a business admissibility subsystem BSS,

SQL Code
  1. --Customer Data sheet
  2. Create Table Customers
  3. (
  4. CUSTOMER_ID Number (8) not null, --Customer indication
  5. City_name Varchar2 (Ten) not null, --City
  6. Customer_type char (2) not null, --Customer type
  7. ...
  8. )
  9. Create unique index pk_customers on customers (customer_id)

For some reason, the information in the customer's city is not accurate, but
Customer service in the CRM subsystem, through proactive services to obtain a portion of the customer 20% is located
City and so on, you extract that part of the information into a temporary table:

SQL Code
    1. Create table Tmp_cust_city
    2. (
    3. CUSTOMER_ID Number (8) is not null,
    4. Citye_name Varchar2 (Ten) not null,
    5. Customer_type char (2) not null
    6. )

1) The simplest form

SQL Code
    1. --confirmed Customers table all customer_id less than 1000 are ' Beijing '
    2. where customer_id<1000

2) Two tables (multiple tables) associated update --only in the WHERE clause of the connection

SQL Code
    1. --the extracted data are VIP and include new, so update the customer category
    2. --using aliases
    3. set customer_type= " --01" for VIP, 00 is normal
    4. where exists (select 1
    5. from tmp_cust_city b
    6. where b.customer_id=a.customer_id
    7. )

3) Two tables (multiple tables) associated Update- -the modified value is calculated by another table

SQL Code
  1. Update customers a --using aliases
  2. Set City_name= (select B.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
  3. where exists (select 1
  4. From Tmp_cust_city b
  5. where b.customer_id=a.customer_id
  6. )
  7. --Update more than 2 values
  8. Update customers a --using aliases
  9. Set (City_name,customer_type) = (select B.city_name,b.customer_type
  10. From Tmp_cust_city b
  11. where b.customer_id=a.customer_id)
  12. where exists (select 1
  13. From Tmp_cust_city b
  14. where b.customer_id=a.customer_id
  15. )

Note In this statement,
= (Select b.city_name,b.customer_type from tmp_cust_city b
where b.customer_id=a.customer_id)
And
(Select 1 from tmp_cust_city b
where b.customer_id=a.customer_id)
is two independent subqueries, to view the execution plan, the B/Index scan 2 ;
If you discard the where condition, the default is to make a table full table
Updated, but because

SQL Code
    1. Select B.city_name from tmp_cust_city b where b.customer_id=a.customer_id

It may not be possible to provide a "sufficient" value because Tmp_cust_city is only part of the customer's information, so an error (if the specified column--city_name can be null is another matter):

SQL Code
    1. 01407, 00000, "Cannot update (%s) to NULL"
    2. *cause:
    3. *Action:

An alternative approach can take:

SQL Code
    1. Update customers a --using aliases
    2. Set CITY_NAME=NVL ((select B.city_name from tmp_cust_city b where b.customer_id=a.customer_id), A.city_name )

Or

SQL Code
    1. SET&NBSP;CITY_NAME=NVL ((select b.city_name  from tmp_cust_city b where b.customer_id= a.customer_id), ' unknown ')


--Of course it doesn't fit the business logic.

4) the above 3) in some cases, since the record of Table B is only a 20-30% of the number ofrecords,
Considering the use of index in a table, using the cursor may result in better performance than the associated update:

SQL Code
  1. Set Serveroutput on
  2. Declare
  3. Cursor City_cur is
  4. Select Customer_id,city_name
  5. From tmp_cust_city
  6. Order by customer_id;
  7. Begin
  8. For my_cur in City_cur loop
  9. Update Customers
  10. Set City_name=my_cur.city_name
  11. where customer_id=my_cur.customer_id;
  12. /** here can also be submitted in single/batch, avoid the lock table situation **/
  13. --If mod (city_cur%rowcount,10000) =0 Then
  14. --Dbms_output.put_line ('----');
  15. --commit;
  16. --End If;
  17. End Loop;
  18. End


5) A special case of associated update and its performance re-discussion
In Oracle's update statement syntax, in addition to the Update table, you can also be a view, so there are 1 exceptions:

SQL Code
    1. Update (Select A.city_name,b.city_name as new_name
    2. From customers A,
    3. Tmp_cust_city b
    4. where b.customer_id=a.customer_id
    5. )
    6. Set City_name=new_name


This avoids 2 scans of table B or its index, but only if a (customer_id) b (customer_id) must be a unique index or primary key. otherwise error:

SQL Code
    1. 01779, 00000,  "cannot modify a column which maps to a non key-preserved table "
    2. //*cause:an attempt was made to insert  or update columns of a  join view which
    3. //map to a non- Key-preserved table.
    4. //*action: modify the underlying base tables directly.


6) Another common error with Oracle
Back to 3) situation, for some reason, tmp_cust_city customer_id is not the only index/primary key

SQL Code
    1. update customers a --using aliases
    2. set city_name= (select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
    3. where exists ( select 1
    4. from tmp_cust_city b
    5. where b.customer_id=a.customer_id
    6. )

When for a given a.customer_id
(Select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id)
Returns the case of excess 1 , the following error is reported:

SQL Code
    1. 01427, 00000, "Single-row subquery returns more than one row"
    2. *cause:
    3. *Action:

A comparatively simple approximation to irresponsible practice is

SQL Code
    1. update customers a --using aliases
    2. set city_name= (select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id  and rownum=1)

How to understand 01427 errors, in a very complex multi-table connection Update statement, often due to ill-conceived, this error occurs,
As described in the example above, a simpler approach is to use the A-table in the value expression, using Group by and
Having words to view duplicate records

SQL Code
    1. (Select B.customer_id,b.city_name,count (*)
    2. From Tmp_cust_city b,customers A
    3. where b.customer_id=a.customer_id
    4. GROUP BY B.customer_id,b.city_name
    5. Having count (*) >=2
    6. )

------------------------------------------------------------

http://blog.itpub.net/29378313/viewspace-1064069/

Oracle Multi-Table Association UPDATE statement

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.