Как передать символ, хранящийся в таблице, в условие хранимой процедуры? - PullRequest
0 голосов
/ 06 декабря 2018

У нас есть 2 таблицы, как показано ниже:

Таблица 1 :

call c1 c2 
---- -- -- 
c001  a  10
c001  a  11
c001  b  13
c001  b  25

Таблица 2 :

call description symbol limit
---- ----------- ------ -----
c001  Gain         >      10
c002  loss         <      1
c003  safe         =      0

Я пытаюсь написать хранимую процедуру, где мы можем передать символ и ограничение, чтобы получить результаты.

SELECT 
    t1.call, t1.c1, (t1.C2 - t2.C2)     
    CASE ( MOD(t1.c2-t2.c2) t3.symbol (select t3.limit from table2 t3), 'FAIL', 'PASS') STATUS
FROM 
    table1 t1, table1 t2
WHERE 
    t1.C1 = t2.C1 AND t3.call = t1.call

и результат выглядит так:

call c1 c2 STATUS
---- -- -- ------
C001 a  1  FAIL
C001 b  12 PASS

Пожалуйста, помогите.

1 Ответ

0 голосов
/ 06 декабря 2018

Вы можете использовать другой уровень выражения регистра, чтобы решить, какой символ использовать:

select t1a.call, t1a.c1, t1a.c2, t1b.c2,
  t1a.c2 - t1b.c2 as diff, t2.symbol, t2.limit,
  case t2.symbol
    when '>' then
      case when t1a.c2-t1b.c2 > t2.limit then 'PASS' else 'FAIL' end
    when '<' then
      case when t1a.c2-t1b.c2 < t2.limit then 'PASS' else 'FAIL' end
    when '=' then
      case when t1a.c2-t1b.c2 = t2.limit then 'PASS' else 'FAIL' end
  end as status
from table1 t1a
join table1 t1b on t1b.call = t1a.call and t1b.c1 = t1a.c1 and t1b.c2 < t1a.c2
join table2 t2 on t2.call = t1a.call
order by t1a.call, t1b.c1;

CALL C1 C2 C2       DIFF S      LIMIT STATUS
---- -- -- -- ---------- - ---------- ------
c001 a  11 10          1 >         10 FAIL  
c001 b  25 13         12 >         10 PASS  

Но существует значительное повторение, поэтому, если у вас есть несколько символов для работы с ним, оно не будет хорошо масштабироваться,по крайней мере, для удобства обслуживания.

В качестве более общего, хотя и немного более неясного, подхода вы можете отскочить через своего рода динамическую оценку через тип XML:

select t1a.call, t1a.c1, t1a.c2, t1b.c2,
  t1a.c2 - t1b.c2 as diff, t2.symbol, t2.limit,
  xmlquery('/ROWSET/ROW/*/text()'
  passing xmltype(
    dbms_xmlgen.getxml('select case when ' || (t1a.c2-t1b.c2) || t2.symbol || t2.limit
      || ' then ''PASS'' else ''FAIL'' end from dual')
  )
  returning content) as status
from table1 t1a
join table1 t1b on t1b.call = t1a.call and t1b.c1 = t1a.c1 and t1b.c2 < t1a.c2
join table2 t2 on t2.call = t1a.call
order by t1a.call, t1b.c1;

CALL C1 C2 C2       DIFF S      LIMIT STATUS
---- -- -- -- ---------- - ---------- ------
c001 a  11 10          1 >         10 FAIL  
c001 b  25 13         12 >         10 PASS  

Или вы можете использоватьdymanic SQL, создающий аналогичную строку для запуска и оценки.

В любом случае это болезненно и неловко, поэтому вы можете захотеть взглянуть на другие способы захвата бизнес-правил.

I 'Мы также должны были догадаться, что вы можете решить, какую из двух строк вычесть из другой, исходя из того, что одна из них больше.Но это также предполагает, что они не могут быть равными - если они могут быть, тогда условие соединения не найдет их вообще (и если вы измените условие соединения, оно будет сопоставлять строки самим себе, поэтому вам придется проверитьтакже разные идентификаторы строк).

db <> fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...