Как правильно использовать oracle в запросе, условия «Если» и «НРАВИТСЯ» - PullRequest
0 голосов
/ 31 марта 2020

Мне нужна помощь с кодом, у меня есть две части кода, которые пишут две переменные: v_responsible_job и v_responsible. Я хотел бы объединить эти запросы в один и добавить условие, если.

Если ответ на это запрос "AB C", тогда первый запрос должен быть выполнен, а если нет, второй запрос:

https://dbfiddle.uk/?rdbms=oracle_18&fiddle=4ce28fad7e33f00c5538e49943ae7dechere - это демонстрационные данные

SELECT NAME FROM data_separators WHERE id = way.DS_ID

пример ответа:

NAME

ABC Info
Scool
offise
ABC SHOP

первый вызов:

BEGIN
  SELECT full_name, job INTO v_responsible, job_id
    FROM physical_persons
    WHERE id IN (SELECT physical_person
                   FROM data_separators WHERE id = way.DS_ID) AND rownum = 1;

  SELECT name
    INTO v_responsible_job
    FROM jobs
    WHERE id = job_id AND
          rownum = 1;

  if v_responsible_job is not null then
    if length(v_responsible_job) > 0 then
      v_responsible_job := ', '|| v_responsible_job;
    end if;
  end if;
     EXCEPTION WHEN OTHERS THEN
           v_responsible_job := '';
     END;

второй вызов:

  BEGIN
  SELECT full_name, job
    INTO v_responsible, job_id
    FROM physical_persons
    WHERE id IN (SELECT RESPONSIBLE
                   FROM ADRESSES
                   WHERE name = p1.name) AND
          rownum = 1;

  SELECT name
    INTO v_responsible_job
    FROM jobs
    WHERE id = job_id AND 
          rownum = 1;

  if v_responsible_job is not null then
    if length(v_responsible_job) > 0 then
      v_responsible_job := ', '|| v_responsible_job;
    end if;
  end if;
        EXCEPTION WHEN OTHERS THEN
           v_responsible_job := '';
     END;

мой вариант ответа, но его не работает (

         BEGIN
   
           select count(*)  into  v_count_word FROM data_separators WHERE id = way.DS_ID and  NAME LIKE '%ABC%';
           select count(RESPONSIBLE)  into  v_count_respon FROM ADRESSES WHERE name = p1.name;
           
         if v_count_word > 0 then       
             SELECT full_name, job INTO v_responsible, job_id FROM physical_persons WHERE id IN (SELECT physical_person FROM data_separators WHERE id = way.DS_ID) AND rownum = 1;
             SELECT name INTO v_responsible_job FROM jobs WHERE id = job_id AND rownum = 1;
             if v_responsible_job is not null then
                if length(v_responsible_job) > 0 then
                v_responsible_job := ', '|| v_responsible_job;
                end if;
             end if;
          end if; 


          if v_count_respon > 0 and  v_count_word = 0 then
           SELECT full_name, job INTO v_responsible, job_id FROM physical_persons WHERE id IN (SELECT RESPONSIBLE
                   FROM ADRESSES
                   WHERE name = p1.name) AND rownum = 1;

           SELECT name INTO v_responsible_job FROM jobs  WHERE id = job_id AND rownum = 1;

                      if v_responsible_job is not null then
                        if length(v_responsible_job) > 0 then
                          v_responsible_job := ', '|| v_responsible_job;
                        end if;
                      end if;
        end if;                              
        if      v_count_respon = 0 and v_count_word  = 0 then   
             SELECT full_name, job INTO v_responsible, job_id FROM physical_persons WHERE id IN (SELECT physical_person FROM data_separators WHERE id = way.DS_ID) AND rownum = 1;
             SELECT name INTO v_responsible_job FROM jobs WHERE id = job_id AND rownum = 1;
             if v_responsible_job is not null then
                if length(v_responsible_job) > 0 then
                v_responsible_job := ', '|| v_responsible_job;
                end if;
             end if;
        end if;
         EXCEPTION WHEN OTHERS THEN
             v_responsible_job := '-';
   END;    

1 Ответ

0 голосов
/ 31 марта 2020

Объедините первые два запроса, используя EXISTS, а затем используйте LISTAGG для агрегирования значений:

DECLARE
  v_responsible_jobs VARCHAR2(4000);
BEGIN
  SELECT LISTAGG( name, ',' ) WITHIN GROUP ( ORDER BY name )
  INTO   v_responsible_jobs
  FROM   jobs j
  WHERE  EXISTS(
    SELECT 1
    FROM   physical_persons pp
    WHERE  pp.job_id = j.job_id
    AND    id IN (
      SELECT physical_person
      FROM   data_separators
      WHERE  id = way.DS_ID
    )
  );
END;
/

Другой способ - использовать BULK COLLECT INTO тип данных коллекции и затем выполнить итерацию поверх коллекции, соединяющей строку; но это сложнее, чем использовать LISTAGG, чтобы сделать всю работу за вас.

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