如果输入是对象的 json 数组,则解包以从 ORDS plsql 块获取数据

问题描述 投票:0回答:1

我在 Oracle ORDS 中使用下面的 PLSQL 块,其中我当前的输入 json 正文如下

['123','456']

但我想将输入的json正文更改为以下格式(无法决定逻辑)

[{
"vendorid":123"
}]

我当前的工作代码如下(对于输入主体 ['123','456']),我不明白如何更改下面以接受所需的 json 主体,

DECLARE
    -- JSON Object and Array to hold the final response and data
    L_JSON_OBJECT   JSON_OBJECT_T := JSON_OBJECT_T();
    L_JSON_ARRAY    JSON_ARRAY_T := JSON_ARRAY_T();
    L_SUPPLIER_DATA JSON_OBJECT_T;
    
    -- Variable to hold the parsed JSON array of vendor_ids from the request body
    L_VENDOR_IDS JSON_ARRAY_T;
    L_VENDOR_ID  NUMBER;

    -- Cursor to fetch matching records with non-null EXP_DATE and ensure uniqueness
    CURSOR C_GET_SUPPLIERS (P_VENDOR_ID NUMBER) IS
        SELECT DISTINCT 
            VENDOR_ID,
            EXP_DATE
        FROM 
            XXMIC_AP_SUPP_DETAILS_OUT_T
        WHERE 
            VENDOR_ID = P_VENDOR_ID
            AND EXP_DATE IS NOT NULL
            AND SYSDATE < EXP_DATE;  -- Ensuring we only fetch records with future expiration dates

    -- Record to store each row fetched from the cursor
    L_SUPPLIER_ROW C_GET_SUPPLIERS%ROWTYPE;
    
    -- Status and description
    L_STATUS VARCHAR2(10);
    L_MESSAGE VARCHAR2(4000);
    
BEGIN
    -- Parse the JSON array from the request body
    L_VENDOR_IDS := JSON_ARRAY_T.PARSE(:body);  -- Assuming :body holds the input vendor_id array

    -- Iterate over the list of vendor_ids
    FOR I IN 1 .. L_VENDOR_IDS.GET_SIZE LOOP
        -- Fetch each vendor_id from the JSON array
        L_VENDOR_ID := L_VENDOR_IDS.GET_NUMBER(I);

        -- Open the cursor to fetch supplier records
        OPEN C_GET_SUPPLIERS(L_VENDOR_ID);
        LOOP
            FETCH C_GET_SUPPLIERS INTO L_SUPPLIER_ROW;
            EXIT WHEN C_GET_SUPPLIERS%NOTFOUND;

            -- Create a new JSON object for each supplier record
            L_SUPPLIER_DATA := JSON_OBJECT_T();
            L_SUPPLIER_DATA.PUT('vendor_id', L_SUPPLIER_ROW.VENDOR_ID);
            L_SUPPLIER_DATA.PUT('exp_date', TO_CHAR(L_SUPPLIER_ROW.EXP_DATE, 'YYYY-MM-DD'));

            -- Append the JSON object to the JSON array
            L_JSON_ARRAY.APPEND(L_SUPPLIER_DATA);
        END LOOP;

        CLOSE C_GET_SUPPLIERS;

        -- If no records found for the current vendor_id, set the status to error
        IF L_JSON_ARRAY.GET_SIZE = 0 THEN
            L_STATUS := 'ERROR';
            L_MESSAGE := 'No matching records with valid EXP_DATE found for vendor_id: ' || L_VENDOR_ID;
        ELSE
            L_STATUS := 'SUCCESS';
            L_MESSAGE := 'Successfully retrieved data';
        END IF;
    END LOOP;

    -- Build the final JSON object
    L_JSON_OBJECT.PUT('status', L_STATUS);
    L_JSON_OBJECT.PUT('message', L_MESSAGE);
    L_JSON_OBJECT.PUT('data', L_JSON_ARRAY);

    -- Output the JSON response
    OWA_UTIL.MIME_HEADER('application/json', TRUE);
    HTP.P(L_JSON_OBJECT.TO_CLOB);

EXCEPTION
    WHEN OTHERS THEN
        -- Handle any errors and return an error JSON response
        L_JSON_OBJECT := JSON_OBJECT_T();
        L_JSON_OBJECT.PUT('status', 'ERROR');
        L_JSON_OBJECT.PUT('message', 'An error occurred: ' || SQLERRM);
        L_JSON_OBJECT.PUT('data', JSON_ARRAY_T());

        OWA_UTIL.MIME_HEADER('application/json', TRUE);
        HTP.P(L_JSON_OBJECT.TO_CLOB);
END;

我的表结构如下

SEQ_ID                  NOT NULL NUMBER        
VENDOR_ID               NOT NULL NUMBER        
PARTY_ID                         NUMBER        
VENDOR_NUMBER                    VARCHAR2(30)  
VENDOR_START_DATE                DATE          
VENDOR_END_DATE                  DATE          
VENDOR_NAME                      VARCHAR2(360) 
PARTY_SITE_ID                    NUMBER        
VENDOR_SITE_ID          NOT NULL NUMBER        
VENDOR_SITE_CODE                 VARCHAR2(50)  
SITE_START_DATE                  DATE          
SITE_END_DATE                    DATE          
BUSINESS_RELATION_SHIP           VARCHAR2(30)  
CREATION_DATE                    DATE          
LAST_UPDATE_DATE                 DATE          
FUSION_CREATION_DATE             DATE          
FUSION_LAST_UPDATE_DATE          DATE          
FUSION_CREATED_BY                VARCHAR2(64)  
FUSION_LAST_UPDATED_BY           VARCHAR2(64)  
BUSINESS_UNIT_ID                 NUMBER        
EXP_DATE                         DATE   
sql plsql oracle-sqldeveloper oracle-rest-data-services
1个回答
0
投票

您不需要游标和循环,并且可以在单个查询中完成所有操作:

DECLARE
  L_JSON        CLOB;
BEGIN
  SELECT JSON_OBJECT(
           KEY 'status' VALUE CASE COUNT(*)
                              WHEN 0
                              THEN 'ERROR'
                              ELSE 'SUCCESS'
                              END,
           KEY 'message' VALUE CASE COUNT(*)
                              WHEN 0
                              THEN 'No matching records with valid EXP_DATE found'
                              ELSE 'Successfully retrieved data'
                              END,
           KEY 'data' VALUE JSON_ARRAYAGG(
             JSON_OBJECT(
               KEY 'vendor_id' VALUE s.vendor_id,
               KEY 'exp_date'  VALUE s.exp_date
             )
           )
         )
  INTO   L_JSON
  FROM   JSON_TABLE(
           :body,
           '$[*]'
           COLUMNS (
             vendorid NUMBER PATH '$.vendorid'
           )
         ) v
         INNER JOIN XXMIC_AP_SUPP_DETAILS_OUT_T s
         ON (v.vendorid = s.vendor_id)
  WHERE  SYSDATE < EXP_DATE;

  -- Output the JSON response
  OWA_UTIL.MIME_HEADER('application/json', TRUE);
  HTP.P(L_JSON);
EXCEPTION
  WHEN OTHERS THEN
    DECLARE
      L_JSON_OBJECT JSON_OBJECT_T;
    BEGIN
      -- Handle any errors and return an error JSON response
      L_JSON_OBJECT := JSON_OBJECT_T();
      L_JSON_OBJECT.PUT('status', 'ERROR');
      L_JSON_OBJECT.PUT('message', 'An error occurred: ' || SQLERRM);
      L_JSON_OBJECT.PUT('data', JSON_ARRAY_T());

      OWA_UTIL.MIME_HEADER('application/json', TRUE);
      HTP.P(L_JSON_OBJECT.TO_CLOB);
    END;
END;
/
© www.soinside.com 2019 - 2024. All rights reserved.