Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Nhận chi tiết tài khoản trong Oracle bằng cách sử dụng chức năng

Bạn có vẻ hơi hỗn loạn trong việc mô tả vấn đề, vui lòng định dạng câu hỏi của bạn và làm cho nó dễ đọc hơn. Dù sao các giải pháp là đơn giản. Bạn chỉ cần một if câu lệnh, trong đó, tùy thuộc vào cấp độ, bạn tìm kiếm trong bảng đầu tiên hoặc bảng thứ hai và cột thích hợp:

create or replace function get_accountdetails (par_input in varchar2) return varchar2 is
  v_aid varchar2(10);
  v_db  varchar2(10);
  v_lvl varchar2(10);
  v_ret varchar2(20) := '';
begin
  v_aid := regexp_substr(par_input, '\d+', 1, 1);
  v_db  := regexp_substr(par_input, '\d+', 1, 2);
  v_lvl := regexp_substr(par_input, '\d+', 1, 3);

  if v_lvl = 1 then
     select dim_cust_key
       into v_ret
       from dim_cust_acnt
       where level1_account_id = v_aid and database_id = v_db;
  elsif v_lvl = 2 then
     select dim_cust_key
       into v_ret
       from dim_cust_dept
       where level2_account_id = v_aid and database_id = v_db;
  else
     select dim_cust_key
       into v_ret
       from dim_cust_dept
       where level3_account_id = v_aid and database_id = v_db;
  end if;
  return v_ret;
end;

Đây là bảng và các lệnh gọi hàm mẫu:

create table dim_cust_acnt (dim_cust_key, level1_account_id, database_id) as (
    select 1123, 112, 22 from dual union all
    select 1234, 113, 23 from dual );

create table dim_cust_dept (dim_cust_key, level2_account_id, level3_account_id, database_id) as (
    select 1587, 245, 301, 21 from dual union all
    select 1576, 289, 304, 20 from dual);

select get_accountdetails('[112].[22].[1]') from dual;     -- result: 1123
select get_accountdetails('[289].[20].[2]') from dual;     -- result: 1576
select get_accountdetails('[301].[21].[3]') from dual;     -- result: 1587

Vui lòng sử dụng tên cột thích hợp mà bạn có trong dữ liệu thực của mình, đồng thời điều chỉnh độ dài và loại biến nếu cần. Tôi nghĩ bạn cũng có thể sử dụng một truy vấn đã kết hợp, không cần hàm đặc biệt, giống như bên dưới. Tôi đã sử dụng full join , bởi vì các ví dụ của bạn không chứa các hàng phù hợp. Có thể đơn giản join sẽ đủ.

with t(par_input) as (select '[112].[22].[1]' from dual)
select dim_cust_key
  from dim_cust_acnt a
  full join dim_cust_dept d using (dim_cust_key) 
  cross join t
  where ( 1 = regexp_substr(par_input, '\d+', 1, 3)  
          and regexp_substr(par_input, '\d+', 1, 1) = level1_account_id 
          and regexp_substr(par_input, '\d+', 1, 2) = a.database_id )
     or ( 2 = regexp_substr(par_input, '\d+', 1, 3)  
          and regexp_substr(par_input, '\d+', 1, 1) = level2_account_id 
          and regexp_substr(par_input, '\d+', 1, 2) = d.database_id )
     or ( 3 = regexp_substr(par_input, '\d+', 1, 3)  
          and regexp_substr(par_input, '\d+', 1, 1) = level3_account_id 
          and regexp_substr(par_input, '\d+', 1, 2) = d.database_id )

Kết quả:

DIM_CUST_KEY
------------
        1123

Nếu bạn xóa withcross join các bộ phận và thêm into thì bạn có thể sử dụng truy vấn này trong hàm thay vì if tuyên bố.

Chỉnh sửa:

Xin lỗi vì sự chậm trễ, tôi đã không xem Stack Overflow gần đây. Dưới đây là hai ví dụ về cách viết các hàm của bạn:

Hàm này trả về chuỗi được nối:

select get_details_1('[112].[22].[1],[289].[20].[2],[301].[21].[3]') as list from dual;

LIST
------------------
1123,1576,1587

Và hàm thứ hai là pipelined và trả về dữ liệu dưới dạng tập hợp các chuỗi được xác định trước, vì vậy các giá trị nằm trong các hàng riêng biệt.

select column_value 
  from table(get_details_2('[112].[22].[1],[289].[20].[2],[301].[21].[3]'));

COLUMN_VALUE
------------
        1123
        1576
        1587

Lúc đầu, bạn cũng có thể phân tích cú pháp tất cả dữ liệu đầu vào, lưu trữ chúng trong một số bộ sưu tập và sau đó sử dụng bộ sưu tập hàng loạt trong một truy vấn. Có nhiều giải pháp và khả năng, cá nhân tôi sẽ sử dụng hàm pipelined, nhưng nó phụ thuộc vào dạng đầu ra bạn cần (tập hợp hoặc chuỗi nối). Ngoài ra, bạn có thể thêm begin ... end chặn và xử lý ngoại lệ when no_data_found . Sau đó, bạn có thể trình bày thông tin đặc biệt hoặc ngắt thời gian thực hiện, điều đó phụ thuộc vào hành vi nào được mong đợi trong tình huống đó.

Chức năng 1:

create or replace function get_details_1 (par_input in varchar2) return varchar2 is
    v_aid varchar2(10);
    v_db  varchar2(10);
    v_lvl varchar2(10);
    v_ret varchar2(20);
    v_all varchar2(200) := '';

    i_cnt int := 0;
begin
    loop
        v_aid := regexp_substr(par_input, '\d+', 1, i_cnt + 1);
        v_db  := regexp_substr(par_input, '\d+', 1, i_cnt + 2);
        v_lvl := regexp_substr(par_input, '\d+', 1, i_cnt + 3);
        i_cnt := i_cnt + 3;
    exit when v_aid is null;
        select dim_cust_key
          into v_ret
          from dim_cust_acnt a
          full join dim_cust_dept d using (dim_cust_key)
          where (v_lvl = 1 and level1_account_id = v_aid and a.database_id = v_db)
             or (v_lvl = 2 and level2_account_id = v_aid and d.database_id = v_db)
             or (v_lvl = 3 and level3_account_id = v_aid and d.database_id = v_db);
       v_all := v_all||','||v_ret;
  end loop;
  return ltrim(v_all, ',');
end;

Chức năng 2:

create or replace function get_details_2 (par_input in varchar2) 
    return sys.odcinumberlist pipelined is

    v_aid varchar2(10);
    v_db  varchar2(10);
    v_lvl varchar2(10);
    v_ret varchar2(20);
    i_cnt int := 0;
begin
    loop
        v_aid := regexp_substr(par_input, '\d+', 1, i_cnt + 1);
        v_db  := regexp_substr(par_input, '\d+', 1, i_cnt + 2);
        v_lvl := regexp_substr(par_input, '\d+', 1, i_cnt + 3);
        i_cnt := i_cnt + 3;
    exit when v_aid is null;
        select dim_cust_key
          into v_ret
          from dim_cust_acnt a
          full join dim_cust_dept d using (dim_cust_key)
          where (v_lvl = 1 and level1_account_id = v_aid and a.database_id = v_db)
             or (v_lvl = 2 and level2_account_id = v_aid and d.database_id = v_db)
             or (v_lvl = 3 and level3_account_id = v_aid and d.database_id = v_db);
       pipe row (v_ret);
  end loop;
  return;
end;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để tạo gói trong Oracle SQL Developer?

  2. Oracle PLSQL tương đương với ASCIISTR (N'str ')

  3. ORA-01775:chuỗi lặp lại các từ đồng nghĩa

  4. bao nhiêu CPU một phiên tiêu thụ tại một thời điểm nhất định trong oracle

  5. Cố gắng xuất một Oracle qua PL / SQL sẽ đưa ra ngày từ 0000-00-00