下面是我的存储过程,我尝试使用 pl/sql 语句访问端点并读取 json 响应。我需要从使用 JSON_OBJECT 和 JSON_ARRAY 的响应中提取数据。我使用的是 Oracle 19 及以上版本,并且能够访问 JSON 库。我不确定为什么会遇到 PLS-00302 错误,因为必须声明组件“COUNT”、“GET_OBJECT”、“GET_ARRAY”。
create or replace PROCEDURE ProcessTableauReportMetadata(
tenant_identifier VARCHAR2
) IS
-- Declare variables
offset NUMBER := 0;
limit NUMBER := 50;
json_response CLOB;
totalResults NUMBER;
-- JSON parsing variables
json_obj JSON_OBJECT_T;
items JSON_ARRAY_T;
item JSON_OBJECT_T;
-- Data processing variables
workbook_uuid VARCHAR2(36);
datasource_uuid VARCHAR2(36);
BEGIN
LOOP
-- Construct endpoint URL with parameters
endpoint_url := 'https://' || tenant_identifier || '.api.us.devhealtheintent.com/business- intelligence/v1/reports?biType=TABLEAU&lite=false&offset=' || offset || '&limit=' || limit;
-- Begin HTTP request
req := UTL_HTTP.BEGIN_REQUEST(endpoint_url, 'GET');
UTL_HTTP.SET_TRANSFER_TIMEOUT(100);
UTL_HTTP.SET_HEADER(req, 'Authorization', 'Bearer ' || 'TOKEN'); -- Replace with actual token
-- Execute HTTP request
resp := UTL_HTTP.GET_RESPONSE(req);
-- Read the entire JSON response as text
UTL_HTTP.READ_TEXT(resp, json_response);
-- Parse JSON response using built-in JSON parsing functions
json_obj := JSON_OBJECT_T.PARSE(json_response);
items := json_obj.GET_ARRAY('items');
-- Extract totalResults from JSON response
totalResults := json_obj.GET_NUMBER('totalResults');
-- Process each item in the JSON response
FOR i IN 1 .. items.COUNT LOOP
item := items.GET_OBJECT(i);
-- Extract workbook_uuid and associatedSources from the item
workbook_uuid := item.GET_STRING('id');
associatedSources := item.GET_ARRAY('associatedSources');
-- Check for non-empty associatedSources
IF associatedSources.COUNT > 0 THEN
datasource_uuid := associatedSources.GET_OBJECT(1).GET_STRING('id');
-- Update datasource_uuid in TABLEAU_USAGE_WORKBOOK_METADATA table
UPDATE TABLEAU_USAGE_WORKBOOK_METADATA
SET DATASOURCE_UUID = datasource_uuid
WHERE WORKBOOK_UUID = workbook_uuid;
END IF;
END LOOP;
-- Close the HTTP response
UTL_HTTP.END_RESPONSE(resp);
-- Increment offset for the next API call
offset := offset + limit;
-- Exit the loop if totalResults is reached
EXIT WHEN offset >= totalResults;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
-- Handle exceptions
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
UTL_HTTP.END_RESPONSE(resp);
END ProcessTableauReportMetadata;
我尝试更改声明 JSON_OBJECT 和 JSON_ARRAY 的方式,但没有成功。
忽略缺少的变量声明,问题在于您将
items
视为 PL/SQL 集合类型,但事实并非如此。您还尝试将作为 json_element_t
返回的结果处理为数组和对象,而不是明确地 treat
处理它们。
您可以在文档中阅读有关 JSON 数据结构以及可用于它们的有效方法的更多信息。
所以代替:
FOR i IN 1 .. items.COUNT LOOP
item := items.GET_OBJECT(i);
使用(注意数组是从零开始索引的,而不是像 PL/SQL 数组那样从 1 开始索引):
FOR i IN 0 .. items.GET_SIZE - 1 LOOP
item := TREAT(items.GET(i) AS JSON_OBJECT_T);
然后代替:
IF associatedSources.COUNT > 0 THEN
datasource_uuid := associatedSources.GET_OBJECT(1).GET_STRING('id');
用途:
IF associatedSources.GET_SIZE > 0 THEN
datasource_uuid := TREAT(associatedSources.GET(0) AS JSON_OBJECT_T).GET_STRING('id');
跳过http处理,数据提取部分可以这样完成:
-- Process each item in the JSON response
--FOR i IN 1 .. items.COUNT LOOP
FOR i IN 0 .. items.GET_SIZE - 1 LOOP
-- item := items.GET_OBJECT(i);
item := TREAT(items.GET(i) AS JSON_OBJECT_T);
-- Extract workbook_uuid and associatedSources from the item
workbook_uuid := item.GET_STRING('id');
associatedSources := item.GET_ARRAY('associatedSources');
-- Check for non-empty associatedSources
-- IF associatedSources.COUNT > 0 THEN
IF associatedSources.GET_SIZE > 0 THEN
-- datasource_uuid := associatedSources.GET_OBJECT(1).GET_STRING('id');
datasource_uuid := TREAT(associatedSources.GET(0) AS JSON_OBJECT_T).GET_STRING('id');
-- Update datasource_uuid in TABLEAU_USAGE_WORKBOOK_METADATA table
UPDATE TABLEAU_USAGE_WORKBOOK_METADATA
SET DATASOURCE_UUID = datasource_uuid
WHERE WORKBOOK_UUID = workbook_uuid;
END IF;
END LOOP;