Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

oracle - How to insert a value into a nested table without losing data in that table?

How can I insert new data into an existing row's nested table? For example, I have defined

CREATE OR REPLACE TYPE businessTableForCategories AS TABLE OF VARCHAR(128);
/

CREATE TABLE Category (
name                    VARCHAR(128) PRIMARY KEY,
businesses              businessTableForCategories
) NESTED TABLE businesses STORE AS categoryBusinessTable;

Say in Category there is an entry with name = 'Restaurant' and businesses = businessTableForCategories('xzqpehc234ajdpa8').

How can I insert new data into that nested table for that entry in Category without removing the entry, or losing the data stored in the nested table?

I ask because one of the entries I am trying to insert requires an insert statement that is 25137 characters long, which is way past Oracle's limit for a single command. This is because there are many businesses in the category. I would like to create the category, and then insert the businesses one by one (or maybe small groupings) into the nested table "businesses".

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use the MULTISET UNION [ALL|DISTINCT] operator:

SQL Fiddle

Oracle 11g R2 Schema Setup:

CREATE OR REPLACE TYPE businessTableForCategories AS TABLE OF VARCHAR(128);
/

CREATE TABLE Category (
name                    VARCHAR(128) PRIMARY KEY,
businesses              businessTableForCategories
) NESTED TABLE businesses STORE AS categoryBusinessTable
/

INSERT INTO Category VALUES (
  'Restaurant',
  businessTableForCategories('xzqpehc234ajdpa8')
)
/

UPDATE Category
SET businesses = businesses
                 MULTISET UNION ALL 
                 businessTableForCategories('other_value')
WHERE name = 'Restaurant'
/

Query 1:

SELECT *
FROM   category

Results:

|       NAME |                   BUSINESSES |
|------------|------------------------------|
| Restaurant | xzqpehc234ajdpa8,other_value |

Query 2:

Or use a bind variable to include the collection in the query:

DECLARE
  businesses businessTableForCategories := businessTableForCategories();
BEGIN
  businesses.EXTEND( 10000 );
  FOR i IN 1 .. 10000 LOOP
    businesses(i) := DBMS_RANDOM.STRING( 'x', 128 );
  END LOOP;
  INSERT INTO Category VALUES ( 'lots of data', businesses );
END;

Query 3:

SELECT name, CARDINALITY( businesses )
FROM   Category

Results:

|         NAME | CARDINALITY(BUSINESSES) |
|--------------|-------------------------|
| lots of data |                   10000 |
|   Restaurant |                       2 |

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...