sql - DONDE EN condición de no aceptar el valor de cadena
oracle plsql (4)
No es un trabajo así. Tu expresión es igual a
SELECT * FROM table_name WHERE USERNAME = ''''''abc123'''', ''''xyz456'''', ''''pqr789'''''';
Por eso no se encontraron resultados.
Podrías hacer algo como esto, para lograr el efecto de deseo:
SELECT * FROM table_name WHERE user_data like ''%'''''' || USERNAME || ''''''%'';
Pero no sería lo mismo sin embargo.
Estoy construyendo dinámicamente una cadena con el nombre user_data en el procedimiento PL / Sql agregando USERNAME, comillas simples ('') y comas (,) del formulario
''abc123'',''xyz456'',''pqr789''
Pero cuando paso esta cadena a la condición WHERE IN de la instrucción SELECT
SELECT * FROM table_name WHERE USERNAME IN (user_data)
Está lanzando una excepción NO_DATA_FOUND.
Por otro lado, si mi cadena contiene solo un usuario sin las comillas, puede encontrar a ese usuario y mostrar la salida deseada.
El tipo de datos de la cadena user_data es varchar2.
Puede una cadena dinámica en su cláusula
IN
con algo como esto:
SQL> declare
2 user_data varchar2(1000);
3 vSQL varchar2(2000);
4 type tabUser is table of varchar2(16);
5 outData tabUser;
6 begin
7 user_data := ''''''abc'''', ''''123'''', ''''zzz'''''';
8 --
9 vSQL := ''select userName from table_name where username in ('' || user_data || '')'';
10 --
11 execute immediate vSQL bulk collect into outData;
12 --
13 dbms_output.put_line(''user_data: '' || user_data);
14 for i in outData.first .. outData.last loop
15 dbms_output.put_line(''User: '' || outData(i));
16 end loop;
17 end;
18 /
user_data: ''abc'', ''123'', ''zzz''
User: abc
User: 123
PL/SQL procedure successfully completed.
SQL> select * from table_name;
USERNAME
----------------
abc
ABC
123
En este caso, siempre debe usar nombres entre comillas en su cadena, sin importar si tiene uno o más nombres de usuario.
Puedes hacerlo usando una colección:
CREATE TYPE VARCHAR2s_Table IS TABLE OF VARCHAR2(100);
/
Luego ingrese sus datos de esta manera:
SELECT *
FROM table_name
WHERE user_data MEMBER OF VARCHAR2s_Table( ''abc123'',''xyz456'',''pqr789'' );
Alternativamente :
Puede crear una función para dividir los datos y generar la colección:
CREATE TYPE VARCHAR2_TABLE AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION split_String(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT '',''
) RETURN VARCHAR2_TABLE DETERMINISTIC
AS
p_result VARCHAR2_TABLE := VARCHAR2_TABLE();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
END IF;
END IF;
RETURN p_result;
END;
/
Entonces puedes hacer:
SELECT *
FROM table_name
WHERE user_data MEMBER OF split_String( ''abc123,xyz456,pqr789'', '','' );
o:
SELECT *
FROM table_name
WHERE user_data MEMBER OF split_String( TRIM( '''''''' FROM ''''''abc123'''',''''xyz456'''',''''pqr789'''''' ), '''''','''''' );
Su declaración selecta
SELECT * FROM table_name WHERE USERNAME IN (user_data)
será tratado como
SELECT * FROM table_name WHERE USERNAME = ''abc123'',''xyz456'',''pqr789''
lo cual no es correcto
Una alternativa es
SELECT * FROM table_name WHERE INSTR(user_data, USERNAME) > 0