2011-06-14 17 views
8

Soy nuevo en PL-SQL, y me cuesta encontrar una documentación clara de las operaciones que son tablas anidadas. Corrija cualquier terminología mal utilizada, etc.Buscar varchar específico en Oracle Tabla anidada

Tengo un tipo de tabla anidada que utilizo como parámetro para un procedimiento almacenado.

CREATE OR REPLACE TYPE "STRARRAY" AS TABLE OF VARCHAR2 (255) 

En mi procedimiento almacenado, la tabla se inicializa y completa. Digamos que tengo una variable VARCHAR2, y quiero saber verdadero o falso si ese varchar existe en la tabla anidada.

me trataron

strarray.exists('somevarchar') 

pero me sale un ORA-6502

¿Existe una manera más fácil de hacer que, aparte de la iteración?

FOR i IN strarray.FIRST..strarray.LAST 
    LOOP 
     IF strarray(i) = value THEN 
      return 1;--found 
     END IF; 
    END LOOP; 

Respuesta

8

Para la comprobación de valor única que prefiero el operador de "miembro".

[email protected]> declare 
     2  enames  strarray; 
     3  wordToFind varchar2(255) := 'King'; 
     4 begin 
     5  select emp.last_name bulk collect 
     6  into enames 
     7  from employees emp; 
     8  if wordToFind member of enames then 
     9   dbms_output.put_line('Found King'); 
    10  end if; 
    11 end; 
    12/

Found King 

PL/SQL procedure successfully completed 

[email protected]> 
5

Puede utilizar el operador MULTISET INTERSECT para determinar si la cadena que le interesa existe en la colección. Por ejemplo

declare 
    l_enames strarray; 
    l_interesting_enames strarray := new strarray('KING'); 
begin 
    select ename 
    bulk collect into l_enames 
    from emp; 
    if(l_interesting_enames = l_interesting_enames MULTISET INTERSECT l_enames) 
    then 
    dbms_output.put_line('Found King'); 
    end if; 
end; 

imprimirá "Encontrado Rey" si la cadena "REY" es un elemento de la colección l_enames.

3

Debe pasar un índice de matriz, no un valor de matriz a exists en caso de que desee determinar si este elemento existe en la recopilación. Las tablas anidadas están indexadas por enteros, por lo que no hay forma de referenciarlas por cadenas.

Sin embargo, es posible que desee ver las matrices asociativas en lugar de colecciones en caso de que desee hacer referencia a su elemento de matriz por índice de cadena. Esto se verá así:

DECLARE 
    TYPE assocArray IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100); 
    myArray assocArray; 
BEGIN 

    myArray('foo') := 'bar'; 

    IF myArray.exists('baz') THEN 
    dbms_output.put_line(myArray('baz')); 

    ELSIF myArray.exists('foo') THEN 
    dbms_output.put_line(myArray('foo')); 

    END IF; 

END; 

Básicamente, si los valores de la matriz son distintos, puede crear matrices emparejadas referencia a unos de otros, como, arr('b') := 'a'; arr('a') := 'b';

Esta técnica podría ayudar a buscar fácilmente cualquier elemento y su índice.

3

Cuando una tabla anidada se declara como un tipo de nivel de esquema, como lo ha hecho, se puede usar en cualquier consulta SQL como una tabla. Para que pueda escribir una función simple de este modo:

CREATE OR REPLACE FUNCTION exists_in(str VARCHAR2, tab stararray) 
    RETURN BOOLEAN 
    AS 
    c INTEGER; 
    BEGIN 
    SELECT COUNT(*) 
     INTO c 
     FROM TABLE(CAST(tab AS strarray)) 
     WHERE column_value = str; 
    RETURN (c > 0); 
    END exists_in; 
Cuestiones relacionadas