programing

사례 및 IN을 사용한 업데이트 - Oracle

testmans 2023. 6. 9. 21:53
반응형

사례 및 IN을 사용한 업데이트 - Oracle

SQL Server에서 매력적으로 작동하는 쿼리를 작성했습니다.안타깝게도 Oracle db에서 실행해야 합니다.어떻게 변환할 것인지에 대한 해결책을 찾아 웹을 샅샅이 뒤졌지만, 성공하지 못했습니다 :/

쿼리는 다음과 같습니다. iSQL:

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`

제 문제는 또한 그 칼럼들이budgetpost_gr1그리고 예산 게시물은 영숫자이며 Oracle은 목록을 숫자로 보고 싶어하는 것 같습니다.목록은 쉼표로 구분된 목록으로 미리 정의된 변수/매개 변수로, 쿼리에 덤프됩니다.

당신은 예산 게시물이 영숫자라고 말했습니다.이는 문자열과의 비교를 찾고 있다는 것을 의미합니다.매개변수를 작은 따옴표로 묶어야 합니다(그리고 사례 식의 마지막 부분을 놓쳤습니다).

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 

사용하다to_number개종하기 위해budgpost숫자로:

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

편집: 충분한지 확인합니다.9에 있는to_number가장 큰 예산 게시물과 일치합니다.

숫자가 아닌 예산 게시물이 있는 경우 다음과 같이 필터링할 수 있습니다.where쿼리 끝에 있는 절:

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

실행할 수 있는 솔루션이 있습니다.하지만 그것이 최적인지는 모르겠습니다.제가 하는 일은 http://blogs.oracle.com/aramamoo/2010/05/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement.html 에 따라 문자열을 나누는 것입니다.

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

그래서 제 최종 코드는 다음과 같습니다.$bp_gr1'와 같은 문자열입니다.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;

더 빨리 달릴 수 있는 방법이 있습니까?

"목록은 쉼표로 구분된 목록으로 미리 정의된 변수/매개 변수입니다."당신의 질문이 실제로는

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`

그렇다면 문자열을 가져와서 숫자 목록으로 구문 분석하는 함수가 필요합니다.

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;
/

그런 다음 다음과 같은 기능을 사용할 수 있습니다.

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'

조인을 사용하여 업데이트하는 데 사용할 수 있는 다른 해결 방법이 있습니다.아래 예제에서는 룩업 값(이 경우 테이블에 사용자 이름 저장)을 포함하여 테이블을 정규화하지 않을 것으로 가정합니다.업데이트에는 이름을 찾기 위한 조인이 포함되며 출력은 이름을 찾거나 찾을 수 없음을 지원하는 CASE 문에서 평가됩니다.이 작업의 핵심은 조인에서 나오는 모든 열에 고유한 이름이 있는지 확인하는 것입니다.샘플 코드에서 b.user_name이(가) a.user_name 열과 충돌하며 고유한 이름 "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;   

언급URL : https://stackoverflow.com/questions/5170864/update-with-case-and-in-oracle

반응형