2011-01-12 18 views
7

Tengo una cadena delimitada por comas que quiero usar en una cláusula "IN" de la instrucción. por ejemplo: 100.101.102Usando la cláusula "IN" con una cadena delimitada por comas del resultado de una función replace() en Oracle SQL

ya que en la cláusula y "IN" Tengo que citar las cuerdas individial, utilizo una función de reemplazar: por ejemplo: seleccione '' '' || sustituir ('100101102', '',' '', '' ') ||' '' 'desde dual;

La consulta anterior funciona, sin embargo, cuando trato de usar el resultado de lo anterior como una entrada a la cláusula "IN", no devuelve datos. Estoy restringido solo por declaraciones SQL, por lo que no puedo usar el código PL/SQL. Amablemente ayuda.

select * from employee where employee_number in (
    select ''''||replace('100,101,102',',',''', ''')||'''' from dual); 

Lo anterior no funciona. Por favor, hágame saber lo que me estoy perdiendo.

+0

es el número de ID de la lista limitada? –

Respuesta

9

El enfoque general en este caso sería analizar la lista separada por comas en una colección de Oracle y usar esa colección en su instrucción de SQL. Tom Kyte tiene un ejemplo de esto en su discusión en variable IN lists.

Suponiendo que se crea el tipo y la función myTableType in_list de ese hilo, debe ser capaz de hacer

SELECT * 
    FROM employee 
WHERE employee_number IN (
    SELECT * 
     FROM TABLE(in_list(p_your_comma_separated_list)) 
    ) 
+0

Hola Justin, gracias por la sugerencia. Lamentablemente, no tengo acceso a la base de datos para cambiar o crear nada. Solo tengo acceso de lectura, por lo tanto, estoy restringido a solo "seleccionar". – Thomas

4

SQL puro, pero no muy bien probado ...

select to_number(substr(postfix, 2, instr(postfix, ',' ,2)-2)) id 
    from (
     select substr(val, instr(val, ',', 1, n)) postfix 
     from (select ',101,102,103,' val from dual) 
    , (
     select level n 
     from dual 
     connect by level < 10) 
    where instr(val, ',', 1, n) > 0) 
where instr(postfix, ',' ,2)> 2; 

EDITAR: mejorado

select substr(postfix, 1, instr(postfix, ',' ,1)-1) 
    from (
     select substr(val, instr(val, ',',1, level)+1) postfix 
     from (select ',101,102,103,' val from dual) 
     connect by instr(val, ',', 2, level) > 0 
); 

Nota:

  • pre/post fijar las cuerdas con comas
  • adoptar el límite superior (10 en el ejemplo) según sus necesidades (no es necesario en la versión mejorada).
  • usar la función de tabla in_list mencionado por Justing cueva, que es probablemente mejor :)

de crédito: algo así como que está en el libro de Stéphane Faroult "Aplicaciones Refactorying SQL" (O'Reilly)

+0

Hola Markus, gracias. La solución proporcionada por usted que usa sql puro funciona perfectamente. Gracias a ti y a Justin por tu ayuda. – Thomas

2

A medida que la valores separados por comas contienen sólo dígitos, ¿por qué no intentar algo tan simple como usar:

INSTR(','||my_csv_list_of_values||',', ','||my_search_value||',') <> 0 

ver este ejemplo:

-- some test data 
with employee as (
    select 101 as employee_number from dual 
    union select 200 from dual 
    union select 10 from dual 
    union select 102 from dual) 

-- the actual query 
select * from employee 
    where INSTR(','||'101,102,103,104'||',', ','||employee_number||',') <> 0; 
--     ^^^^^^^^^^^^^^^^^ 
--     your CSV data 

Producir:

EMPLOYEE_NUMBER 
101 
102 
0

usted puede utilizar su enfoque con SUSTITUIR e IN si formatea todo el selecto como una cadena - a continuación, utilizar la cadena, ya sea con refcursor ABIERTO PARA EJECUTAR o INMEDIATA.

-1

Puede usar la función regexp_substr para obtener la salida esperada.
Por ejemplo NOMBRES: = 'SMITH, ALLEN, WARD, JONES'; - aquí "NOMBRES" es la variable/resultado de la entrada esperada. Puede usarse en la cláusula IN.

SQL> select regexp_substr(NAMES,'[^,]+', 1, level) from dual 2 connect by regexp_substr(NAMES, '[^,]+', 1, level) is not null; 


REGEXP_SUBSTR('SMITH,A 
---------------------- 
SMITH 
ALLEN 
WARD 
JONES 

Los itera consulta anterior a través de la cadena separada por comas, las búsquedas de la coma (,) y después se divide la cadena mediante el tratamiento de la coma como delimitador. Devuelve la cadena como una fila, cada vez que golpea un delimitador.
Aquí es una referencia Click Here

SQL> select * from emp where ename in (
    2 select regexp_substr('SMITH,ALLEN,WARD,JONES','[^,]+', 1, level) from dual 
    3 connect by regexp_substr('SMITH,ALLEN,WARD,JONES', '[^,]+', 1, level) is not null); 



    EMPNO ENAME  JOB    MGR HIREDATE   SAL  COMM  DEPTNO 
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 
     7369 SMITH  CLERK   7902 17-DEC-80  800     20 
     7499 ALLEN  SALESMAN  7698 20-FEB-81  1600  300   30 
     7521 WARD  SALESMAN  7698 22-FEB-81  1250  500   30 
     7566 JONES  MANAGER   7839 02-APR-81  2975     20 
+1

Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la crítica] (/ reseña/publicaciones de baja calidad/18420868) –

Cuestiones relacionadas