2017-09-14 4 views
0

J'essayais de faire l'insertion basée sur l'instruction fournie dans ce site.définition de type de collection de plsq

Je peux exécuter cet exemple

CREATE OR REPLACE PROCEDURE test_proc (p_array_size IN PLS_INTEGER DEFAULT 100) 
IS 
TYPE ARRAY IS TABLE OF all_objects%ROWTYPE; 
l_data ARRAY; 

CURSOR c IS SELECT * FROM all_objects; 

BEGIN 
    OPEN c; 
    LOOP 
    FETCH c BULK COLLECT INTO l_data LIMIT p_array_size; 

    FORALL i IN 1..l_data.COUNT 
    INSERT INTO t1 VALUES l_data(i); 

    EXIT WHEN c%NOTFOUND; 
    END LOOP; 
    CLOSE c; 
END test_proc; 
/

De même, je l'ai changé le nom de la table pour une utilisation réelle comme ci-dessous.

CREATE OR REPLACE PROCEDURE test_proc (p_array_size IN PLS_INTEGER DEFAULT 100) 
IS 
TYPE ARRAY IS TABLE OF web.salesline%ROWTYPE; 
l_data ARRAY; 

CURSOR c IS SELECT * FROM web.salesline; 

BEGIN 
    OPEN c; 
    LOOP 
    FETCH c BULK COLLECT INTO l_data LIMIT p_array_size; 

    FORALL i IN 1..l_data.COUNT 
    INSERT INTO t2 VALUES l_data(i); 

    EXIT WHEN c%NOTFOUND; 
    END LOOP; 
    CLOSE c; 
END test_proc; 
/

Mais je reçois l'erreur suivante, même si la table existe et l'accès à partir du schéma que je courais.

SQL> show errors 
Errors for PROCEDURE : 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
6/4  PL/SQL: Item ignored 
6/34  PLS-00201: identifier 'WEB.SALESLINE' must be declared 
11/7  PL/SQL: SQL Statement ignored 
16/9  PL/SQL: ORA-00942: table or view does not exist 
20/5  PL/SQL: SQL Statement ignored 
20/40 PLS-00597: expression 'OBJECTTABLE$' in the INTO list is of wrong 
     type 

23/5  PL/SQL: SQL Statement ignored 
23/27 PL/SQL: ORA-00904: : invalid identifier 
+0

Pouvez-vous créer n'importe quelle procédure en utilisant 'web.salesline'? Comme vous vous connectez en tant que 'web' de toute façon, cela fait-il une différence si vous omettez le nom du schéma codé en dur (c'est généralement une bonne pratique de toute façon). –

+0

Ceci ne serait utilisé que pour le développement, donc typiquement exécuté à partir d'un schéma différent. J'ai essayé de créer un synonyme pour que cette table fonctionne sans 'web' mais échoue toujours avec la même erreur. – user1595858

+0

Dans l'exemple ci-dessus qui échoue, la procédure est-elle créée dans le schéma 'web'? Sinon, 'web' devra accorder le privilège' select' au propriétaire de la procédure. (Ceci s'applique à toute référence à des objets dans un autre schéma, pas seulement pour les définitions de type collection, c'est pourquoi j'ai demandé si vous pouviez compiler toute procédure se référant à 'web.salesline'.) –

Répondre

0

À moins que la procédure est créée dans le schéma web, vous faites référence à la table d'un autre schéma, et que le schéma a besoin de vous donner la permission de l'utiliser directement. Notez qu'il n'y a aucun rôle dans la procédure stockée.

Lorsque l'utilisateur WEB:

grant select on salesline to devuser; 

(ou quel que soit le schéma de la procédure réside dans).

En général, nous essayons d'éviter les noms de schéma hardcoding et au lieu de gérer ces références en utilisant des synonymes, de manière DEVUSER:

create or replace synonym salesline for web.salesline; 

Les rôles reviennent en jeu si vous définissez la procédure authid current_user (la valeur par défaut est authid definer), mais ce n'est généralement pas une bonne idée pour les procédures qui exécutent DML.