initcap ejemplos sql oracle sql-update

initcap - case en sql ejemplos



ACTUALIZACIÓN con CASE e IN-Oracle (5)

Escribí una consulta que funciona como un encanto en SQL Server. Desafortunadamente, debe ejecutarse en una base de datos Oracle. He estado buscando en la web una solución de cómo convertirla, sin éxito: /

La consulta se ve así en SQL:

UPDATE tab1 SET budgpost_gr1= CASE WHEN (budgpost in (1001,1012,50055)) THEN ''BP_GR_A'' WHEN (budgpost in (5,10,98,0)) THEN ''BP_GR_B'' WHEN (budgpost in (11,876,7976,67465)) ELSE ''Missing'' END`

Mi problema también es que las columnas budgetpost_gr1 y budgetpost son alfanuméricas y Oracle parece querer ver la lista como números. La lista son variables / parámetros que están predefinidos como listas separadas por comas, que simplemente se vuelcan en la consulta.


"La lista son variables / parámetros que están predefinidos como listas separadas por comas". ¿Quieres decir que tu consulta es en realidad

UPDATE tab1 SET budgpost_gr1= CASE WHEN (budgpost in (''1001,1012,50055'')) THEN ''BP_GR_A'' WHEN (budgpost in (''5,10,98,0'')) THEN ''BP_GR_B'' WHEN (budgpost in (''11,876,7976,67465'')) ELSE ''Missing'' END`

Si es así, necesitas una función para tomar una cadena y analizarla en una lista de números.

create type tab_num is table of number; create or replace function f_str_to_nums (i_str in varchar2) return tab_num is v_tab_num tab_num := tab_num(); v_start number := 1; v_end number; v_delim VARCHAR2(1) := '',''; v_cnt number(1) := 1; begin v_end := instr(i_str||v_delim,v_delim,1, v_start); WHILE v_end > 0 LOOP v_cnt := v_cnt + 1; v_tab_num.extend; v_tab_num(v_tab_num.count) := substr(i_str,v_start,v_end-v_start); v_start := v_end + 1; v_end := instr(i_str||v_delim,v_delim,v_start); END LOOP; RETURN v_tab_num; end; /

Entonces puedes usar la función así:

select column_id, case when column_id in (select column_value from table(f_str_to_nums(''1,2,3,4''))) then ''red'' else ''blue'' end from user_tab_columns where table_name = ''EMP''


Hay otra solución que puede utilizar para actualizar utilizando una unión. Este ejemplo a continuación asume que desea des-normalizar una tabla incluyendo un valor de búsqueda (en este caso, almacenar un nombre de usuario en la tabla). La actualización incluye una combinación para encontrar el nombre y la salida se evalúa en una declaración CASE que admite que el nombre se encuentre o no se encuentre. La clave para hacer que esto funcione es asegurar que todas las columnas que salen de la unión tengan nombres únicos. En el código de ejemplo, observe cómo b.user_name entra en conflicto con la columna a.user_name y debe tener un alias con el nombre único "user_user_name".

UPDATE ( SELECT a.user_id, a.user_name, b.user_name as user_user_name FROM some_table a LEFT OUTER JOIN user_table b ON a.user_id = b.user_id WHERE a.user_id IS NOT NULL ) SET user_name = CASE WHEN user_user_name IS NOT NULL THEN user_user_name ELSE ''UNKNOWN'' END;


Tengo una solución que se ejecuta. Aunque no sé si es óptimo. Lo que hago es dividir la cadena de acuerdo con http://blogs.oracle.com/aramamoo/2010/05/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement.html

Utilizando:
select regexp_substr('' 1, 2 , 3 '',''[^,]+'', 1, level) from dual
connect by regexp_substr(''1 , 2 , 3 '', ''[^,]+'', 1, level) is not null;

Entonces mi código final se ve así: ( $bp_gr1'' son cadenas como 1,2,3 ):

UPDATE TAB1 SET BUDGPOST_GR1 = CASE WHEN ( BUDGPOST IN (SELECT REGEXP_SUBSTR ( ''$BP_GR1'', ''[^,]+'', 1, LEVEL ) FROM DUAL CONNECT BY REGEXP_SUBSTR ( ''$BP_GR1'', ''[^,]+'', 1, LEVEL ) IS NOT NULL) ) THEN ''BP_GR1'' WHEN ( BUDGPOST IN (SELECT REGEXP_SUBSTR ( '' $BP_GR2'', ''[^,]+'', 1, LEVEL ) FROM DUAL CONNECT BY REGEXP_SUBSTR ( ''$BP_GR2'', ''[^,]+'', 1, LEVEL ) IS NOT NULL) ) THEN ''BP_GR2'' WHEN ( BUDGPOST IN (SELECT REGEXP_SUBSTR ( '' $BP_GR3'', ''[^,]+'', 1, LEVEL ) FROM DUAL CONNECT BY REGEXP_SUBSTR ( ''$BP_GR3'', ''[^,]+'', 1, LEVEL ) IS NOT NULL) ) THEN ''BP_GR3'' WHEN ( BUDGPOST IN (SELECT REGEXP_SUBSTR ( ''$BP_GR4'', ''[^,]+'', 1, LEVEL ) FROM DUAL CONNECT BY REGEXP_SUBSTR ( ''$BP_GR4'', ''[^,]+'', 1, LEVEL ) IS NOT NULL) ) THEN ''BP_GR4'' ELSE ''SAKNAR BUDGETGRUPP'' END;

¿Hay alguna manera de hacerlo correr más rápido?


Use to_number para convertir budgpost en un número:

when to_number(budgpost,99999) in (1001,1012,50055) THEN ''BP_GR_A''

EDITAR: asegúrese de que haya suficientes 9 en to_number para coincidir con la publicación de presupuesto más grande.

Si hay publicaciones presupuestarias no numéricas, puede filtrarlas con una cláusula where al final de la consulta:

where regexp_like(budgpost, ''^-?[[:digit:],.]+$'')


Usted dijo que budgetpost es alfanumérico. Eso significa que está buscando comparaciones con cadenas. Debería intentar encerrar sus parámetros en comillas simples (y le falta el THEN final en la expresión del Caso).

UPDATE tab1 SET budgpost_gr1= CASE WHEN (budgpost in (''1001'',''1012'',''50055'')) THEN ''BP_GR_A'' WHEN (budgpost in (''5'',''10'',''98'',''0'')) THEN ''BP_GR_B'' WHEN (budgpost in (''11'',''876'',''7976'',''67465'')) THEN ''What?'' ELSE ''Missing'' END