插入后来自POST服务的ORDS响应

时间:2017-03-08 23:45:26

标签: sql oracle api plsql oracle11g

我目前面临艰难的选择:

  • 一方面,如果我使用AutoREST,我可以轻松获得POST响应。但是,我无法根据需要自定义API行为,例如case-insentitive query。

    • 我使用Table对象启用了AutoREST。我知道我可以使用?q={}来进行查询。
    • 但是我不能用不区分大小写的查询数据。
    • 例如,?q={"name":"Chang"}但我希望找到名称为chang的所有日期,而不考虑字母大小写。
    • 我知道我可以定义一个自定义处理程序来执行此操作并以?name=chang进行查询。但是,如果我目前做ords.enable_object,那么无论如何都要在其上进行自定义吗?
  • 另一方面,如果我定义了我需要的每项服务,我就无法获得正确的POST响应。

    • 我正在尝试实现POST服务并在插入后返回某些值(即,将一些值输出到POST的响应)。我尝试了几种但没有运气。
    • 我尝试过声明局部变量,但不会返回。插入后我也尝试过选择。不太好用。我有一个名为insert_customer的过程,其中有多个IN参数和OUT参数为customer_id。但customer_id只是无法胜出。

这是我的例子:

CREATE OR REPLACE PROCEDURE insert_customer (
   p_corporate_key  IN  customers.corporate_key%TYPE,
   p_fullname       IN  customers.fullname%TYPE,
   p_email          IN  customers.email%TYPE,
   p_phone          IN  customers.phone%TYPE,
   p_job_title      IN  customers.job_title%TYPE,
   p_department     IN  customers.department%TYPE,
   p_organization   IN  customers.organization%TYPE,
   p_customer_id    OUT customers.customer_id%TYPE
)
AS
BEGIN
   INSERT INTO customers (corporate_key, fullname, email, phone, job_title, department, organization)
   VALUES (p_corporate_key, p_fullname, p_email, p_phone, p_job_title, p_department, p_organization)
   RETURN customer_id INTO p_customer_id;
EXCEPTION
   WHEN OTHERS
   THEN HTP.print(SQLERRM);
END;
/

BEGIN
   ORDS.DEFINE_SERVICE(
      p_module_name => 'insert.customers' ,
      p_base_path   => '/customers/',
      p_method      => 'POST',
      p_source      => ‘DECLARE
                           l_customer_id number;
                        BEGIN
                           insert_customer(p_corporate_key => :corporate_key,
                              p_fullname      => :fullname,
                              p_email         => :email,
                              p_phone         => :phone,
                              p_job_title     => :job_title,
                              p_department    => :department,
                              p_organization  => :organization
                              p_customer_id  => :l_customer_id);
                        END;'
   );

   COMMIT;
END;

customer_id是触发器生成的增量序列。

我想插入一个客户(包含相关信息),然后返回customer_id

修改

我已单独检查过程insert_customer,并且工作正常。

SQL>variable l_id number;
SQL>exec insert_customer('a', 'a', 'a', 'a', 'a', 'a', 'a', :l_id);

PL/SQL procedure successfully completed.

SQL> print l_id

      L_ID
----------
       102

我还添加了

htp.prn(:corporate_key);
htp.prn(:l_customer_id);

htp.prn(:corporate_key);
htp.prn(l_customer_id);
insert_customer之前p_source执行END之后

但是,只打印corporate_key,而不是l_customer_id

所以我想知道,过程输出值到OUT参数,单独,但不在ORDS的p_source范围内。

2 个答案:

答案 0 :(得分:1)

也许其他人会添加一个更好的解决方案,但是现在我会与你分享我们已经使用了很长一段时间,它的工作正常。

由于这是通过HTTP返回的,我们使用htp包。特别是prn程序。

l_response        := <your returned value>;
htp.prn(l_response);

这里有一点需要注意,htp.prn只接受最多32K的字符串长度。因此,如果您返回的时间比此长(例如CLOB),则需要通过循环

进行

例如,我们在块/过程结束时调用循环过程:

proc_send_clob_response(l_response);

其中proc_send_clob_response定义如下:

PROCEDURE proc_send_clob_response(
                                  i_rest_response IN CLOB
                                 )
AS
  l_response_body_clob  CLOB;
  l_response_length     NUMBER;
  l_response_buffer     VARCHAR2(32767);
  l_response_chunk_size BINARY_INTEGER := 32000;
  l_offset              INTEGER := 1;

BEGIN
    l_response_body_clob := i_rest_response;
    dbms_lob.open(l_response_body_clob, dbms_lob.lob_readonly); 
    l_response_length := dbms_lob.getlength (l_response_body_clob);

    WHILE (l_response_length > 0)
    LOOP
          dbms_lob.read(l_response_body_clob, l_response_chunk_size, l_offset, l_response_buffer);

         htp.prn(l_response_buffer);

         /* Increase Counter */
         l_offset := l_offset + l_response_chunk_size;

         /* Resize CLOB length */
         l_response_length := l_response_length - l_response_chunk_size;

    END LOOP;

    dbms_lob.close(l_response_body_clob); 
EXCEPTION 
WHEN OTHERS THEN
   --your exception handling here
END;

请注意,我们使用htp.prn而不是htp.p,因为htp.p会在最后添加换行符\n,当我们在循环中连接输出时,我们不希望这样做

答案 1 :(得分:0)

好的,我已经解决了我的问题。

问题来自这部分代码:

BEGIN
   ORDS.DEFINE_SERVICE(
      p_module_name => 'insert.customers' ,
      p_base_path   => '/customers/',
      p_method      => 'POST',
      p_source      => ‘DECLARE
                           l_customer_id number;
                        BEGIN
                           insert_customer(p_corporate_key => :corporate_key,
                              p_fullname      => :fullname,
                              p_email         => :email,
                              p_phone         => :phone,
                              p_job_title     => :job_title,
                              p_department    => :department,
                              p_organization  => :organization
                              p_customer_id   => :l_customer_id);
                        END;'
   );

   COMMIT;
END;

在这一行:p_customer_id => :l_customer_id

因为前缀为:的变量被视为p_source之外的变量,例如:corporate_key:fullname,因此l_customer_id在此声明p_source。所以,我需要做的就是删除前面的:并使用htp.prn打印出来,如下所示:

BEGIN
   ORDS.DEFINE_SERVICE(
      p_module_name => 'insert.customers' ,
      p_base_path   => '/customers/',
      p_method      => 'POST',
      p_source      => ‘DECLARE
                           l_customer_id number;
                        BEGIN
                           insert_customer(p_corporate_key => :corporate_key,
                              p_fullname      => :fullname,
                              p_email         => :email,
                              p_phone         => :phone,
                              p_job_title     => :job_title,
                              p_department    => :department,
                              p_organization  => :organization
                              p_customer_id   => l_customer_id);
                           htp.prn(''{"customer_id":"''||l_customer_id||''"}'');
                        END;'
   );

   COMMIT;
END;

请求和回复:

POST /api/schema/customers/ HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: xxx
Content-Type: application/json
Host: url:port
User-Agent: HTTPie/0.9.4

{
    "corporate_key": "a",
    "department": "a",
    "email": "a",
    "fullname": "a",
    "job_title": "a",
    "organization": "a",
    "phone": "a"
}

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Thu, 09 Mar 2017 15:46:49 GMT
Server: Jetty(9.2.z-SNAPSHOT)
Transfer-Encoding: chunked    

{
    "customer_id": "130"
}