2011-11-02 2 views
19

oracle에서 JSON을 사용하여 손쉽게 작업 할 수 있습니까? JSON은 웹 개발 컨텍스트에서 익숙한 형식이지만 웹 서비스를 호출하는 데 사용하는 표준 프로 시저가 있지만 저장 프로 시저 내에서 json을 사용하는 가장 좋은 방법은 무엇입니까? 예를 들어 URI에서 CLOB 응답을 가져 와서 JSON 객체로 변환하고 그 값을 얻으시겠습니까?oracle에서 json으로 작업하십시오.

참조를 위해서

, 여기에 내가 URL을 가져 오는 데 사용되는 절차를 다음

create or replace procedure macp_URL_GET(url_resp in out clob, v_url in varchar2) is 
    req  Utl_Http.req; 
    resp Utl_Http.resp; 
    NAME VARCHAR2 (255); 
    VALUE VARCHAR2 (1023); 
    v_msg VARCHAR2 (80); 
    v_ans clob; 
-- v_url VARCHAR2 (32767) := 'http://www.macalester.edu/'; 
BEGIN 
    /* request that exceptions are raised for error Status Codes */ 
    Utl_Http.set_response_error_check (ENABLE => TRUE); 
    /* allow testing for exceptions like Utl_Http.Http_Server_Error */ 
    Utl_Http.set_detailed_excp_support (ENABLE => TRUE); 
    /* 
    Utl_Http.set_proxy (
     proxy     => 'www-proxy.us.oracle.com', 
     no_proxy_domains  => 'us.oracle.com' 
    ); 
    */ 
    req := Utl_Http.begin_request (url => v_url, method => 'GET'); 
    /* 
    Alternatively use method => 'POST' and Utl_Http.Write_Text to 
    build an arbitrarily long message 
    */ 

    /* 
    Utl_Http.set_authentication (
     r    => req, 
     username  => 'SomeUser', 
     PASSWORD  => 'SomePassword', 
     scheme   => 'Basic', 
     for_proxy  => FALSE  --this info is for the target Web server 
    ); 
    */ 

    Utl_Http.set_header (r => req, NAME => 'User-Agent', VALUE => 'Mozilla/4.0'); 
    resp := Utl_Http.get_response (r => req); 
    /* 
    DBMS_OUTPUT.put_line ('Status code: ' || resp.status_code); 
    DBMS_OUTPUT.put_line ('Reason phrase: ' || resp.reason_phrase); 
    FOR i IN 1 .. Utl_Http.get_header_count (r => resp) 
    LOOP 
     Utl_Http.get_header (r => resp, n => i, NAME => NAME, VALUE => VALUE); 
     DBMS_OUTPUT.put_line (NAME || ': ' || VALUE); 
    END LOOP; 
    */ 
--test 
    BEGIN 
     LOOP 
     Utl_Http.read_text (r => resp, DATA => v_msg); 
     --DBMS_OUTPUT.put_line (v_msg); 
     v_ans := v_ans || v_msg; 
     url_resp := url_resp || v_msg; 
     END LOOP; 
    EXCEPTION 
     WHEN Utl_Http.end_of_body 
     THEN 
     NULL; 
    END; 
--test 
    Utl_Http.end_response (r => resp); 


    --url_resp := v_ans; 

EXCEPTION 
    /* 
    The exception handling illustrates the use of "pragma-ed" exceptions 
    like Utl_Http.Http_Client_Error. In a realistic example, the program 
    would use these when it coded explicit recovery actions. 

    Request_Failed is raised for all exceptions after calling 
    Utl_Http.Set_Detailed_Excp_Support (ENABLE=>FALSE) 
    And it is NEVER raised after calling with ENABLE=>TRUE 
    */ 
    WHEN Utl_Http.request_failed 
    THEN 
     DBMS_OUTPUT.put_line (
     'Request_Failed: ' || Utl_Http.get_detailed_sqlerrm 
    ); 
     url_resp :='Request_Failed: ' || Utl_Http.get_detailed_sqlerrm; 
    /* raised by URL http://xxx.oracle.com/ */ 
    WHEN Utl_Http.http_server_error 
    THEN 
     DBMS_OUTPUT.put_line (
     'Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm 
    ); 
     url_resp := 'Http_Server_Error: ' || Utl_Http.get_detailed_sqlerrm; 
    /* raised by URL http://otn.oracle.com/xxx */ 
    WHEN Utl_Http.http_client_error 
    THEN 
     DBMS_OUTPUT.put_line (
     'Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm 
    ); 
     url_resp := 'Http_Client_Error: ' || Utl_Http.get_detailed_sqlerrm; 
    /* code for all the other defined exceptions you can recover from */ 
    WHEN OTHERS 
    THEN 
     DBMS_OUTPUT.put_line (SQLERRM); 
     url_resp := SQLERRM; 
END; 

이는

begin 
    macp_url_get(url_resp => :url_resp, 
       'http://maps.googleapis.com/maps/api/geocode/json?address=55105&sensor=false'); 
end; 

(나는 googleapi가 XML 응답을 허용 것을 알고 있지만, 다른있다 테스트 할 수있다

+1

이 작업을 수행 할 수 있다고 생각하지 않지만 API를 작성한 사람들이 있습니다 [ http://reseau.erasme.org/pl-sql-library-for-JSON?lang=en] (JSON 용 pl/sql 라이브러리 - 예를 들어 테스트 해 보았을 것입니다. 아주 간단합니다) & [ sourceforge.net/projects/pljson/] (pljson - 더 복잡해 보이지만 작동해야 함) – Harrison

답변

18
:

만 Oracle 데이터를 추출하고 JSON에서 변환하려면이 라이브러리는 약간 내가 더 빨리 그 일을 당신에게 다른 코드를 제안 할 수 ... "사용하는 헤비"입니다

나는이 라이브러리를 사용하기 시작했으며, 유망한 것으로 보인다 : https://github.com/pljson/pljson

쉬운 설치와 예제가 좋다.

그런 다음 당신은 JSON 객체로 응답을 조작 할 수

mapData  json; 
results  json_list; 
status  json_value; 
firstResult json; 
geometry json; 

... .. 프로 시저에 다음 변수를 추가, 당신의 예에서 라이브러리를 사용합니다.

-- convert the result from the get to a json object, and show some results. 
mapData := json(v_ans); 

-- Show the status of the request 
status := mapData.get('status'); 
dbms_output.put_line('Status = ' || status.get_string()); 

IF (status.get_string() = 'OK') THEN 
    results := json_list(mapData.get('results')); 
    -- Grab the first item in the list 
    resultObject := json(results.head); 

    -- Show the human readable address 
    dbms_output.put_line('Address = ' || resultObject.get('formatted_address').to_char()); 
    -- Show the json location data 
    dbms_output.put_line('Location = ' || resultObject.get('geometry').to_char()); 
END IF; 

DBMS의 출력이 코드가 출력이 실행 :

오라클 (12c)의로 JSON의 몇 가지 기본 지원이 있음을 주목해야한다
Status = OK 
Address = "St Paul, MN 55105, USA" 
Location = { 
    "bounds" : { 
    "northeast" : { 
     "lat" : 44.9483849, 
     "lng" : -93.1261959 
    }, 
    "southwest" : { 
     "lat" : 44.9223829, 
     "lng" : -93.200307 
    } 
    }, 
    "location" : { 
    "lat" : 44.9330076, 
    "lng" : -93.16290629999999 
    }, 
    "location_type" : "APPROXIMATE", 
    "viewport" : { 
    "northeast" : { 
     "lat" : 44.9483849, 
     "lng" : -93.1261959 
    }, 
    "southwest" : { 
     "lat" : 44.9223829, 
     "lng" : -93.200307 
    } 
    } 
} 
+1

이 라이브러리는 GitHub https://github.com/pljson/pljson – Damian

2

나는이 라이브러리를 작성했습니다 : http://reseau.erasme.org/pl-sql-library-for-JSON?lang=en, 그리고 이것은 json 응답을 plsql 테이블에 넣기 위해 훌륭하게 작동합니다.

create or replace package jsonfly as 

procedure open_object(k varchar2 default null); 
procedure close_object; 
procedure open_array (k varchar2 default null); 
procedure close_array; 
procedure separation; 
procedure member(k varchar2, v varchar2); 
procedure member(k varchar2, n number); 
procedure send; 
end; 
/

create or replace package body jsonfly as 
-------------------------------------------------------------------------------- 
-- package pour générer du JSON, envoyé à la volé 
-------------------------------------------------------------------------------- 
type tCache is table of varchar2(2000) index by binary_integer; 

g_openBrace   constant varchar2(2) := '{ '; 
g_closeBrace  constant varchar2(2) := ' }'; 
g_openBracket  constant varchar2(2) := '[ '; 
g_closeBracket  constant varchar2(2) := ' ]'; 
g_stringDelimiter constant varchar2(1) := '"'; 
g_Affectation  constant varchar2(3) := ' : '; 
g_separation  constant varchar2(3) := ', '; 
g_CR    constant varchar2(1) := Chr(10); -- used to indent the JSON object correctly 
g_spc    constant varchar2(2) := ' ';  -- used to indent the JSON object correctly 
g_js_comment_open constant varchar2(20) := '/*-secure-\n'; -- used to prevent from javascript hijacking 
g_js_comment_close constant varchar2(20) := '\n*/';   -- used to prevent from javascript hijacking 

--isObjectOpened boolean := false; 
--isArrayOpened boolean := false; 
t tCache; 
i number := 1; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure p(s varchar2) is 
begin 
    t(i) := s; 
    i := i + 1; 
end; 
-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
function encap (s varchar2) return varchar2 is 
begin 
    return g_stringdelimiter || s || g_stringdelimiter; 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
function encode_string(p_string varchar2) return varchar2 is 
begin 
    return replace(replace(replace(replace(replace(replace(replace(replace(p_string, 
     '\', '\\'), 
     '"', '\"'), 
     '/', '\/'), 
     chr(8), '\b'), 
     chr(9), '\t'), 
     chr(10), '\n'), 
     chr(12), '\f'), 
     chr(13), '\r'); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure open_object(k varchar2 default null) is 
begin  
    if (k is null) then 
     p(g_openbrace); 
    else 
     p(encap(k) || g_affectation || g_openbrace); 
    end if; 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure close_object is 
begin 
    if (t(i-1) = g_separation) then 
     i := i - 1; 
    end if; 
    p(g_closebrace); 
    separation(); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure open_array (k varchar2 default null) is 
begin  
    if (k is null) then 
    p(g_openbracket); 
    else 
     p(encap(k) || g_affectation || g_openbracket); 
    end if; 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure close_array is 
begin 
    if (t(i-1) = g_separation) then 
     i := i - 1; 
    end if; 
    p(g_closebracket); 
    separation(); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure separation is 
begin 
    p(g_separation); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure key(k varchar2) is 
begin 
    p(encap(k) || g_affectation); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure value(v varchar2) is 
begin 
    p(v); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure member(k varchar2, v varchar2) is 
begin 
    p(encap(k) || g_affectation || encap(encode_string(v))); 
    p(g_separation); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure member(k varchar2, n number) is 
begin 
    p(encap(k) || g_affectation || n); 
    p(g_separation); 
end; 

-------------------------------------------------------------------------------- 
-- 
-------------------------------------------------------------------------------- 
procedure send is 
begin 
    if (t(i-1) = g_separation) then 
     t.delete(i-1); 
    end if; 

    i := t.first; 
    while (i is not null) loop 
     htp.p(t(i)); 
     i := t.next(i); 
    end loop; 
end; 


end jsonfly; 
/
3

. 그러나 나는 현재의 형태로 PLJSON이 다른 대답에 포함되어있는 것처럼 유용하다고 생각하지 않습니다.

이 기능을 사용하려면 BLOB, CLOB 또는 Varchar2 필드가있는 테이블을 만들고 "열 IS JSON"제약 조건을 추가하십시오. 이렇게하면 해당 열에 JSON 구문 검사가 적용됩니다.

"IS JSON"제약 조건이있는 한 SQL의 점 표기법을 사용하여 JSON 값에 액세스 할 수 있습니다. 나에게 PLJSON만큼 강력한 조작을 제공하지 않는 것 같습니다. XMLType을 작성한 다음 JSON으로 변환 할 수도 있습니다.

유용한 링크 :
Oracle docs
Good tutorial and examples
Tutorial including XML to JSON

1

오라클 APEX 5.0은 JSON이 APEX_JSON 패키지를 사용하여 지원합니다. 나는 그것을 사용하지 않았지만 재미있어 보였고 팀에 조사를 요청했습니다.우리의 유스 케이스는 JSON 데이터를 입력 매개 변수로 nodejs 애플리케이션에서 저장 프로 시저로 전달하는 것이다.

+0

으로 이동했음을 유의해야합니다. APEX 5.0 서버를 설치하지 않고 APEX_JSON 패키지를 기존 데이터베이스에 설치합니다. 우리는 pljson (https://github.com/pljson/pljson) 라이브러리를 사용하기로 결정했습니다. – Parvez

1

오라클 12C 지금 native JSON support 있습니다

오라클 데이터베이스 트랜잭션, 색인, 선언 쿼리 및 뷰

JSON 데이터와 XML 데이터를 포함 관계형 데이터베이스 기능과 기본적으로 자바 스크립트 객체 표기법 (JSON) 데이터를 지원 할 수 유사한 방식으로 Oracle Database에서 사용됩니다. 관계형 데이터와는 달리, 데이터를 정의하는 스키마가 필요없이 둘 다 저장, 인덱싱 및 쿼리 할 수 ​​있습니다. Oracle Database는 트랜잭션, 인덱싱, 선언적 쿼리 및 뷰와 같은 관계형 데이터베이스 기능을 사용하여 JSON을 기본적으로 지원합니다.

JSON 데이터는 Oracle NoSQL 데이터베이스 및 Oracle Berkeley DB와 같은 NoSQL 데이터베이스에 저장되는 경우가 많습니다. 이는 스키마에 기반하지 않은 데이터의 저장 및 검색을 허용하지만 관계형 데이터베이스의 엄격한 일관성 모델을 제공하지는 않습니다.

이 단점을 보완하기 위해 관계형 데이터베이스가 NoSQL 데이터베이스와 병렬로 사용되는 경우가 있습니다. NoSQL 데이터베이스에 저장된 JSON 데이터를 사용하는 응용 프로그램은 데이터 무결성 자체를 보장해야합니다.

Oracle Database에서 JSON을 기본 지원하면 이러한 대안을 피할 수 있습니다. 트랜잭션, 인덱싱, 선언적 쿼리 및 뷰를 비롯하여 JSON에서 사용할 관계형 데이터베이스 기능의 모든 이점을 제공합니다.

Oracle Database 쿼리는 선언적입니다. 관계형 데이터로 JSON 데이터를 조인 할 수 있습니다. JSON 데이터를 관계형으로 투영하여 관계형 프로세스 및 도구에서 사용할 수 있도록 할 수 있습니다. 외부 테이블의 데이터베이스 외부에 저장된 JSON 데이터를 데이터베이스 내에서 쿼리 할 수도 있습니다.

OCI, .NET 및 JDBC 사용을 포함하여 다른 데이터베이스 데이터에 액세스하는 것과 같은 방법으로 데이터베이스에 저장된 JSON 데이터에 액세스 할 수 있습니다.

SQL 데이터 유형 XMLType을 사용하여 저장된 XML 데이터와 달리 JSON 데이터는 SQL 데이터 유형 VARCHAR2, CLOB 및 BLOB를 사용하여 Oracle 데이터베이스에 저장됩니다. 오라클은 항상 is_json check 제약 조건을 사용하여 열 값이 유효한 JSON 인스턴스인지 확인합니다.

관련 문제