I've a post method that response with user data, name, id, etc.
{
"allowed": "SI",
"id": 2112,
"name": "Manuela Merlo",
"age": "23"
}
Now, I need add picture information on base 64 over the same response. When the picture is the small size the method work fine.
{
"allowed": "SI",
"id": 2112,
"name": "Manuela Merlo",
"age": "23",
"picture":"/9j/4AAQSkZJRgABAQEAeAB4AAD/....all base 64 here..."
}
but when the image is long size then fails with error ORA-06502: PL/SQL: numeric or value error.
ORDS not support clob parameters at response, only string and long variable is available for store char data.
This is the source code of the Post module on ords
declare
l_user varchar2(100);
begin
l_user :=:username;
:l_allowed:=pkg_users.validate_user(l_user,:password);
:l_id :=l_user;
:l_name :=pkg_users.Get_Name(l_user);
:l_age :=pkg_users.Get_Age(l_user);
:l_picture:=pkg_users.Get_picture(l_user);
end;
I'm not able to create a separete method to reponse on another media type because the client app is not updateable.
Are there any workaourond to responde long size on Ords?
If you return the CLOB as part of a SELECT clause it will work, but returning it as part of the RESPONSE doesn't work, it's limited to 32K, and this make me think that in that case htp.prn() is used behind the scene. So if the only solution for you to return a RESPONSE because you get the results from a procedure, then you should build the whole JSON yourself and use a function that outputs the CLOB using http.prn() by chunk of 32K max.
Related
I need to consume and parse incoming json from a third party system in my code. I used RestTemplate to do it. So the response from the system looks like below.
{ "data": { "05AAAFW9419M11Q": { "gstin": "05AAAFW9419M11Q", "error_cd": "SWEB_9035", "message": "Invalid GSTIN / UID" } } }
Now the problem is the property name ("05AAAFW9419M11Q" in this case) in dynamic and in the next response it would be another string. In this case, how can I parse this json as this is not fixed in Oracle Integration Cloud? Response wrapper is not capturing the data apart from the one that is used for configuring the adapter which is fair enough as fieldname itself is changing.
Is there is any workaround for this?
You will have to go to PL/SQL and dynamic SQL, and if it's always the value of gstin entry, you can get the path of the key with
select '$.data.' ||
json_query(js_column, '$.data.*.gstin') into v_key path from table_with_json_column where ... conditions... ;
(assuming there is only 1 "data" per JSON payload) to later build a dynamic query based on json_table.
I'm using Oracle Rest Data Services to build an app.
I can easily read & write with something like this GET http://example.com/foo/bar that runs query SELECT * FROM bar or
POST http://example.com/foo/bar
{
"first": "a'b",
"second": "c,d"
}
that runs query INSERT INTO bar (first, second) VALUES (:first, :second)
Where query parameters are bound from request body.
Now, I'd like to build a route that run a dynamic query.
I can do that with one binding param, eg.:
POST http://example.com/foo/query
{
"query": "DELETE FROM bar WHERE first = :param",
"param": "a'b"
}
that runs query
BEGIN EXECUTE IMMEDIATE :query USING :param; END;
But I don't know how to do it with multiple params. For eg.
POST http://example.com/foo/query
{
"query": "DELETE FROM bar WHERE first = :first AND second = :second",
"bindings": "first,second",
"first": "a'b",
"second": "c,d"
}
The query should be something like
DECLARE
params ...? -- (params variable should set USING list from :bindings request param)
BEGIN
EXECUTE IMMEDIATE :query USING params;
END;
Any idea?
It's only a small change from your previous example. See this example from the docs for more info.
BEGIN EXECUTE IMMEDIATE :query USING :first, :second; END;
As a warning, the bind variable names in the query don't need to match the names in the EXECUTE IMMEDIATE block - they're evaluated in the order they occur, not by name. So in this example:
:query := 'DELETE FROM bar WHERE first = :a and second = :b';
execute immediate :query using :my_var1, :my_var2;
The value of pl/sql variable my_var1 is assigned to sql bind variable a since they're both the first ones. It can get more complicated if you want to repeat variable names... but I think that's enough to answer your question.
I'm trying to create a Restful service that will return JSON or XML data. The company is using Oracle application express (Restful Services) as the tool for the job.
I've noticed that the latest versions of Application Express the XML option is no longer.?
I was wondering does anyone one have any examples or ideas on how I can can create a Restful service that will return JSON or XML depending on the content type I request ?
I'm currently running Application Express 4.2.5.00.08.
This has always been pretty straight forward in other languages but I need to work it out with oracle data services ORDS
The current setup I have tried is to define a Restful service as follows ;
Resful Service Module :
URI Template : test
Method : GET
Source : Query Format : JSON (XML is no longer option)
Require Secure Access : NO
Source :
SELECT RESTful_Testing.GetSampleData(:contentType) FROM DUAL
Parameters
Name : Accept
Bind Variable Name : contentType
Access Method : IN
Source Type : HTTP Header
Parameter Type : String
I have set it up so I can call an Oracle Package and pass in the content type. The problem I have is that the format is already predefined, so any attempt to return XML would be incorrect ( or can I alter the header later).
The Package Code is Very basic and is as follows just for testing ;
CREATE OR REPLACE PACKAGE APEX_EDS.RESTful_Testing AS
TYPE resultCursor IS REF CURSOR;
function GetSampleData(contentType VARCHAR) return resultCursor;
END RESTful_Testing;
/
CREATE OR REPLACE PACKAGE BODY APEX_EDS.RESTful_Testing AS
function GetSampleData(contentType VARCHAR) return resultCursor AS
O_resultCursor resultCursor;
BEGIN
-- Check the Content Type
IF ( contentType = 'application/xml' ) THEN
OPEN O_resultCursor FOR
select '<ROOT><NAME>John</NAME><SURNAME>Smith</SURNAME>
<CONTENT_TYPE>application/xml</CONTENT_TYPE></ROOT>' FROM DUAL;
return(O_resultCursor);
ELSE -- Assume JSON so return normal
OPEN O_resultCursor FOR
select 'John' FirstName, 'Smith' Surname, contentType ContentType FROM DUAL;
return(O_resultCursor);
END IF;
END;
END RESTful_Testing;
Hope that further adds to my issue and hope there are some oracle ORDS experts out there :).
We are currently doing this on a project with apex. You should be able to find lots of tutorials online. E.g. http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/apex/r42/RESTful_WS_oll/RESTful_WS_oll.html
You can change the type of rest service to return JSON in the example above, but not XML. However it's fairly straightforward with the various xml functions in sql e.g. http://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb13gen.htm#i1029583
I'm sure if you can get your restful services hooked up you should also be able to create a service to return a custom result which you can get from an xml query.
The closest I get is by trying to manually set the output. I determine the content type to be returned from looking what the accept header is being sent by the request.
begin
IF (:contentType = 'application/xml') THEN
--set the response format
owa_util.mime_header('application/xml', true, 'ISO-8859-4');
htp.p('<?xml version="1.0" encoding="UTF-8" ?>');
htp.p('<ROOT>');
htp.p('<NAME>');
htp.p('JOHN');
htp.p('</NAME>');
htp.p('<SURNAME>');
htp.p('SMITH');
htp.p('</SURNAME>');
htp.p('<CONTENT_TYPE>');
htp.p(:contentType);
htp.p('</CONTENT_TYPE>');
htp.p('</ROOT>');
ELSE
owa_util.mime_header('application/json', true);
--quick json here will need to use library to parse query
-- http://sourceforge.net/projects/pljson/ used for real data
htp.p('{"name" : "John" , "surname" : "smith", "content_type" : ' || :contentType || '}');
END IF;
end;
It shows that it can be done but I still would like to here from people out there if there is a more elegant solution.
Thanks
Neil
I notice that r.table('xxx') not always return a cursor but also sometimes just return docs directly
Is the cursor client side implementation only or there are some special things server did to perform queries associate with a cursor?
If it has somethings related to server, what is it and when will I receive a cursor
For example I specify result offset and size with skip and limit in the query. Will server return a cursor or just result docs?
A driver returns a cursor when the query returns a stream.
Basically when the server produces a stream (a sequence that is lazily computed), the driver will return a cursor. As you fetch rows from the cursor, the server will compute more elements in the sequence.
For example, when you run r.table('xxx'), you will get back a cursor. The server will load the documents from disk as you request them with the driver.
In the JavaScript driver, when a query return an array, the driver will sneak an object that mimics the cursor interface between the arrray itself and Array.prototype.
So if query.run(...) returns a sequence, you can just do
query.run(connection).then(function(result) {
return result.toArray()
}).then(function(result) {
// do something with result
}).error(function(err) {
// handle err
})
Basically if you don't want to think if you are getting back a cursor or an array, you can just consider that it's a cursor.
You can read more about stream/cursor here:
http://www.rethinkdb.com/docs/data-types/
I am using QsqlQuery to call oracle stored procedure that uses input parameters and two output parameters
The procedure executed perfectly but output parameters contains no data
QSqlQuery movementQuery ;
movementQuery.prepare("call Qt.add_movement(:pDocumentType , :pDocumentId ,
to_date(sysdate,'dd-mm-yyyy') ,:pDocumentNumber"
",to_date(sysdate,'dd-mm-yyyy') , :pCustId ,:pMovementId ,:pReturn )");
movementQuery.bindValue(":pDocumentType",documentType);
movementQuery.bindValue(":pDocumentId",documentId);
movementQuery.bindValue(":pDocumentNumber",0);
movementQuery.bindValue(":pCustId",ui->custId->text());
movementQuery.bindValue(":pMovementId", 0, QSql::Out);
movementQuery.bindValue(":pReturn", "FALSE", QSql::Out);
movementQuery.exec();
//// The query executed the query is active and no errors are valid
//// message is method to display the value
message(query.boundValue(":pReturn").toString());
message(query.boundValue(5).toString());
message(query.boundValue(":pMovementId").toString());
message(query.boundValue(4).toString());
Any ideas
Thank you for your interest
You are executing movementQuery
movementQuery.exec();
but you are returning the bound values of query.
message(query.boundValue(":pReturn").toString());