Ответ в массиве при запросе в оракуле - PullRequest
1 голос
/ 24 октября 2019

Я разрабатываю ответ на запрос покоя, я почти закончил, но не могу закончить список объектов в массиве. у меня есть код, который возвращает мне JSON вот мой код:

DECLARE
   v_count varchar2(2000);
   v_id                     USERS_C.id%TYPE;
   v_users_name             USERS_C.name%TYPE;
   v_organization_id varchar2(2000);
   v_organization_name      ORGANIZATIONS.NAME%TYPE;
   v_role varchar2(2000);


     CURSOR c_event IS SELECT
            id,
            users_name,
            organization_id,
            organization_name,
            role
                 FROM
                      (SELECT
                              a.*,
                              ROWNUM rnum
                FROM
                    (SELECT
                            ev.id,
                            ev.login users_name  ,
                            ds.id    organization_id,
                            ds.NAME  organization_name,
                            cv.role_names role


                        FROM ORGANIZATIONS_USERS lo
                              LEFT JOIN users_c ev ON ev.ID = lo.USER_ID
                              LEFT JOIN ORGANIZATIONS ds ON lo.ORGANIZATION_ID = ds.id
                              LEFT JOIN APEX_APPL_ACL_USERS cv ON ev.login = cv.USER_NAME
                        ) a
            );

BEGIN


         SELECT
                COUNT(*)
         INTO
                v_count
         FROM    users_c  ;
         IF v_count = 0 THEN

                apex_json.open_object;
                apex_json.write('success', false);
                apex_json.write('message', 'No data found');
                apex_json.write('count', 0);
                apex_json.close_object;
                return;
        END IF;
        OPEN c_event;
        apex_json.open_object;
        apex_json.write('count',v_count);
        apex_json.open_array('items');
        LOOP
            FETCH c_event INTO v_id,v_users_name,v_organization_id,v_organization_name,v_role;
            EXIT WHEN c_event%notfound;
            apex_json.open_object;
            apex_json.write('id', v_id);
            apex_json.write('user', v_users_name );
             apex_json.open_array('datasectors');
             apex_json.write('id', v_organization_id);
             apex_json.write('name', v_organization_name);
             apex_json.close_array;
            apex_json.open_object('roles');
            apex_json.write('role', v_role);
            apex_json.close_object;
            apex_json.close_object;
        END LOOP;
        apex_json.close_all;
        CLOSE c_event;
End;

он возвращает этот ответ:

 "items": [
    {
      "id": 2,
      "user": "andrii",
      "datasectors": [
        "id": "21",
          "name": "TOW3"
      ],
      "roles": {
      "role": "Admin"
      }
    },
    {
      "id": 2,
       "user": "andrii",
      "datasectors": [
        "id": "122",
         "name": "TOW2""
      ],
      "roles": {
       "role": "Admin"
      }
    },
    {
      "id": 2,
      "user": "andrii",
      "datasectors": [
        "id": "62",
        "name": "TOW1""
      ],
      "roles": {
        "role": "Admin"
      }

вы видите, количество моих ответов зависит от количества наборов данныхЯ в. Я хочу, чтобы все были в массивах, это верно

    "items": [
        {
          "id": 2,
          "user": "andrii",
          "datasectors": [{
            "id": "21",
              "name": "TOW3"
            },
            {
            "id": "122",
             "name": "TOW2""
            },
            {
            "id": "62",
            "name": "TOW1"
            }
          ],
          "roles": {
          "role": "Admin"
          }
        }

Вот запрос для каждого, кого я знаю, из всех организаций, которые связывают меня

SELECT
             ds.id    organization_id,  
             ds.NAME  organization_name                        

    FROM ORGANIZATIONS_USERS lo
        LEFT JOIN users_c ev ON ev.ID = lo.USER_ID
         LEFT JOIN ORGANIZATIONS ds ON lo.ORGANIZATION_ID = ds.id
  where df.login = 'andrii'

, и у меня естьпоместить этот ответ в

apex_json.open_array('datasectors');
apex_json.write('id', v_organization_id);
apex_json.write('name', v_organization_name);
apex_json.close_array;

Мой стол

Table :users_c

id      login 
2       Andrii
3       Ira

Table :ORGANIZATIONS_USERS
id       USER_ID    ORGANIZATION_ID
1        2          21
2        2          122
3        2          62
4        3          122
5        3          62

Table :ORGANIZATIONS
id       Name    
21       Tow1          
122      Tow2
62       Tom3
      Table : APEX_APPL_ACL_USERS 
   USER_NAME     ROLE_NAMES
   Andrii       Admіn, Operator
   Ira          Admіn

1 Ответ

2 голосов
/ 24 октября 2019

Вот основная идея:

declare

  v_count number;

begin

  select count(*)
  into v_count
  from users_c;

  if v_count = 0 then
    apex_json.open_object;
    apex_json.write('success', false);
    apex_json.write('message', 'No data found');
    apex_json.write('count', 0);
    apex_json.close_object;

    return;
  end if;

  apex_json.open_object;
  apex_json.write('count', v_count);
  apex_json.open_array('items');

  for user_rec in (
    select id,
      login
    from users_c
  )
  loop
    apex_json.open_object;
    apex_json.write('id', user_rec.id);
    apex_json.write('user', user_rec.login);
    apex_json.open_array('datasectors');

    for org_rec in (
      select id,
        name
      from organizations o
      where id in (
        select organization_id
        from organization_users
        where user_id = user_rec.id
      )
    )
    loop
      apex_json.open_object;
      apex_json.write('id', org_rec.id);
      apex_json.write('name', org_rec.name);
      apex_json.close_object;
    end loop;

    apex_json.close_array; -- datasectors
    apex_json.close_object;
  end loop;

  apex_json.close_array; -- items
  apex_json.close_object;

end;

Если вы используете ORDS на 18c, вероятно, есть лучшее решение для вас, использующее SQL, но вышеупомянутое должно работать в целом.

Единственная проблема, которую я могу заметить, заключается в том, что первый запрос, который получает счетчик users_c, может получить номер, отличный от второго запроса в той же таблице. Есть разные способы решения этой проблемы, но я оставлю это упражнение на ваше усмотрение.

Посмотрите эту серию, чтобы узнать больше вариантов: https://jsao.io/2015/07/relational-to-json-in-oracle-database/

...