Below is part of my plsql code for webservice call, if am hardcoding lv_activity_token code is working fine,same is not working when am getting it from below expression
iv_offset_cnt:=0;
lv_activity_token:= substr(iv_activity_token,instr(iv_activity_token,'/',2)+1);--with this code is not working
--iv_activity_token is coming from oracle table which i stored in table from different web service response
-- lv_activity_token:='2562432'; hardcoding the same value which is coming from above expression,with this code is working
lv_ws_url:='https://secure.p03.eloqua.com:443/api/bulk/2.0/syncs/';
lv_ws_url1:='/data?limit=200&offset=';
gv_ws_url := lv_ws_url || lv_activity_token || lv_ws_url1 || iv_offset_cnt;
--at the end gv_ws_url value is:
--https://secure.p03.eloqua.com:443/api/bulk/2.0/syncs/2562432/data?limit=200&offset=0
additional detials:
gv_ws_url --passing this to get the response.
Please let me know if you need any other details.
(i was doubting with data which is storing in table(may be character set issue))
thanks in advance.
Related
I am trying to develop some REST API and I am working with: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production, Oracle ORDS and SQL Developer 17.3.1.279.
I already develop and test a GET API in order to prove that the db is REST-Enabled.
I try to develop a POST API and I am reading this article
My POST handler is:
declare
lrow accounts%rowtype := null;
begin
lrow.id := :id;
lrow.account := :account;
/*added to inspect the current value*/
Raise_Application_Error(-20000, '*'||:account||'*');
lrow.category := :category;
lrow.address := :address;
lrow.zipcode := :zipcode;
lrow.city := :city;
lrow.county := :county;
ASADMIN.INSERTACCOUNT(lrow);
:error := null;
exception
when others then
:error := sqlerrm;
end;
For each bind variable I create a corresponding in/out parameter in the handler.
I test the API with POSTMAN passing this object:
{
"id" : "18092018"
,"account" : "Buster Keaton"
,"category" : "TEST CATEGORY"
,"address" : "TEST ADDRESS"
,"zipcode" : "12345"
,"city" : "TEST CITY"
,"county" : "TEST COUNTY"
,"error" : null
}
and the response was "Cannot insert NULL in ..." then I add the raise application error in order to check what is the value passed that results as null.
I would like to know which is the common (or best) practice to debug a REST API and the way to "monitor" bind variables.
I try to run the anon block attached to the handler inside of SQL Developer to make sure it's going to work there first. So, does that work, in SQL Developer where you are doing the restful service definition?
For others reading this question, when you want to 'debug' and don't have access to the ORDS server logs:
If you get a 500 response when calling it from ORDS, it can be helpful to run ORDS in 'debug' mode.
There are two properties you can enable, debug and print to screen. (docs)
This will show the stack dump from the back end in your browser - not something you ever want to do in 'prod' but since you're debugging, I'm assuming you're in a safe place.
Once that's on, make your call again -
Now you can see the ORA error code that's causing the 500 - and you can also probably see how ORDS is executing the anon plsql block - maybe you're not processing the inputs correctly...
I talk about this here.
For your case specifically, you either have a typo or you are neglecting a value when it comes to making your call to INSERTACCOUNT().
Without seeing the spec for INSERTACCOUNT(), we're left to guess what might be happening.
After commenting the response from thatjeffsmith I focus on service parameters and bind variables and I realize that my setup was completly wrong. I would like to share how I correct what was my mistake.
In the POST handler I use bind variable that I pass to the service in the body of the request but I define corresponding parameters as IN/OUT so the SOURCE can be only HEADER or URI and the bind variables result all null.
I found very useful theese articles: Parameters and binds and resultset.
I modify the handler deleting ALL the IN/OUT parameters because every variable (or JSON object) passed via request body are automatically "matched" with bind variables used in the handler.
Now I am working/studying on resultset in order to return the well formed json object with all the information needed to my app.
We are trying to execute an oracle function that requires parameters and we are getting the error ORA-01008- Not all variables are bound. We are pretty sure the problem is in how we are binding the variable that is supposed to received the result of the function. First we tried the following (a method without parameters):
$tSql:="select staging.FUNC_ORAOCI_TEST() from dual"
$iStatus:=OCIHandleAlloc (envhp;$stmthp;OCI_HTYPE_STMT)
$iStatus:=OCIHandleAlloc (envhp;$errhp;OCI_HTYPE_ERROR)
$iStatus:=OCIStmtPrepare ($stmthp;$errhp;$tSql;OCI_DEFAULT)
$iStatus:=OCIDefineByPos ($stmthp;$bindpp;$errhp;1;->atResults;SQLT_STR;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;OCI_DEFAULT)
$iStatus:=OCIStmtExecute (svchp;$stmthp;$errhp;1;0;0;0;OCI_DEFAULT)
And it worked perfectly...
Where we got stuck was when trying to pass parameters to the function (which we had modified on purpose to now accept parameters)
We thought it was because we now had to make the binding by name, but it just did not work. We have tried running a PL/SQL block and still we get the error. Here are our failed attempts:
Using a SQL Statement:
$tSql:="select staging.FUNC_ORAOCI_TEST(:tParamText,:iParamNum) from dual"
$iStatus:=OCIBindByName ($stmthp;$bindpp;$errhp;":tParamText";- >tParamText;SQLT_STR;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;1;OCI_DEFAULT;BIND_IN)
$iStatus:=OCIBindByName ($stmthp;$bindpp;$errhp;":iParamNum";->iParamNum;SQLT_INT;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;1;OCI_DEFAULT;BIND_IN)
$iStatus:=OCIDefineByPos ($stmthp;$bindpp;$errhp;1;->atResults;SQLT_STR;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;OCI_DEFAULT)
$iStatus:=OCIStmtExecute (svchp;$stmthp;$errhp;1;0;0;0;OCI_DEFAULT)
Using a PL/SQL Anonymous Block:
$tSql:="DECLARE vResult VARCHAR2:=''; BEGIN vResult := FUNC_ORAOCI_TEST(:tParamText,:iParamNum); End;"
$iStatus:=OCIBindByName ($stmthp;$bindpp;$errhp;":tParamText";->tParamText;SQLT_STR;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;1;OCI_DEFAULT;BIND_IN)
$iStatus:=OCIBindByName ($stmthp;$bindpp;$errhp;":iParamNum";->iParamNum;SQLT_INT;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;1;OCI_DEFAULT;BIND_IN)
$iStatus:=OCIBindByName ($stmthp;$bindpp;$errhp;":vResult";->tResult;SQLT_STR;$ORANullIndicator;$ORANullLenArray;$ORANullReturnCodeArray;1;OCI_DEFAULT;BIND_OUT)
$iStatus:=OCIStmtExecute (svchp;$stmthp;$errhp;1;0;0;0;OCI_DEFAULT)
We have looked at similar questions but no one was trying to use the OCI interface to execute the function the way we are doing it.
We are coding in 4D so ignore the weird syntax. We just need guidance as to how build the statement and what would be the proper OCI command to reach a successful binding.
We partially resolved this issue.
We have got it to work only for SQL statements not for PL/SQL. But we got rid of the ORA-01008 error.
The code in case 1 referenced above works as is. We did some clean up of comments and lines that were added for debugging, but they might have altered the sqlstmt somehow, thus affecting the binds.
The code in case 2 now gives an error "Invalid SQL Statement" which we will open a new inquiry for in separate thread.
One very useful information that we found to help us resolve the initial inquiry can be found here:
https://docs.oracle.com/database/121/LNOCI/oci05bnd.htm#LNOCI16368
Really weird.
I have an Oracle function
function highlightDesc(desc IN VARCHAR2, keyword IN VARCHAR2) return VARCHAR2
return 'paragraphtag' ||
REPLACE(desc, keyword, 'boldtag' || keyword || 'boldtag') || 'paragraphtag';
this gets called this way
select a.*, highlightDesc(a.Desc) as highlightedDesc
from tablea a
The weird thing is that when I call this sql from within sqlplus or plsql developer the highlightedDesc column contains all the right markup.
When I call it from Junit, I get all the right markup.
When I call it from a struts2 app running on jboss(winxp/redhat) with the oracle thin drivers,
I get the enclosing paragraphtag tags and the content but not the boldtag .
Does that make sense?
Any thoughts?
Edit:
I apologize, I cant log into SO from work. Lame I know.
I am using the commons dbutils queryrunner (BeanListHandler) to execute the sql from a java class.
My action is doing nothing but calling my service class and setting the value.
I looked at the src for queryrunner, it ends up calling a class called BeanProcessor which gets the highlightedDesc column as a String via rs.getString(index);
I thought it might be an encoding problem??? so I tried to change the jvm encoding and also the jboss encoding, but it had no effect.
I think I might see if converting the character set in oracle has any effect?
Thanks.
Most likely, the keyword isn't passed correctly to the function, so the REPLACE function does effectively nothing.
I have a java stored procedure that takes in a clob representing a chunk of javascript and mins it. The structure of the function calling the JSP is as follows:
function MIN_JS(pcl_js in clob) return clob as
language java name 'JSMin.min(oracle.sql.CLOB) return oracle.sql.CLOB';
In the actual JSP, I have the following:
import oracle.sql.CLOB;
public class JSMin {
...
public static min(CLOB js) {
...
}
The problem I'm having is that whenever I pass a clob to JS_MIN, it is always interpreted as null inside the JSP. I've checked the clob before calling JS_MIN annd it definitely has contents. Any ideas as to what I'm missing? Any help is greatly appreciated.
As it turns out, one of the javascript chunks I was sending was in fact null. We have several packages that generate javascript for various controls and one is apparently still under development and wrapped in a way that it always returns null unless you are logged in as a particular user.
In my code, I loop across all the javascript packages, sending each to JS_MIN. Everything was working peachy until the package still in development came along and passed null. I added a simple check for null and everything works perfectly now.
So the short answer is: Doh!
Has anyone seen this error when trying to call an external C function from an Oracle query? I'm using Oracle 10g and get this error every time I try to call one of the two functions in the library. A call to the other function returns fine every time, though the function that works is all self-contained, no calls to any OCI* functions.
Here's the stored procedure that is used to call the failing C code:
CREATE OR REPLACE PROCEDURE index_procedure(text in clob, tokens in out nocopy clob, location_needed in boolean)
as language c
name "c_index_proc"
library lexer_lib
with context
parameters
(
context,
text,
tokens,
location_needed
);
Any help would be appreciated. Everything I've found on this error message says that the action to take is: Contact Oracle customer support.
Edit: I've narrowed it down to the point that I know that there is a segfault deep in libclntsh after I call OCILobTrim (to truncate it down to 0 length) on the tokens clob. Here is the code I've been using to call this procedure.
declare text CLOB; tokens CLOB;
begin
dbms_lob.createtemporary(tokens, TRUE);
dbms_lob.append(tokens, 'token');
dbms_lob.createtemporary(text, TRUE);
dbms_lob.append(text, '<BODY>Test Document</BODY>');
index_procedure(text, tokens, FALSE);
dbms_output.put_line(tokens);
end;
/
Is there something wrong with this setup that might be causing OCILobTrim problems?
It looks like this is one of those errors that essentially means any number of things could have gone wrong with the external procedure.
There is a known bug in 10.2.0.3, no idea if it's relevant:
ORA-28579 occurs when trying to select
data from a pipelined table function
implemented in "C" using the
ODCITable/ANYDATASET interface.
ODCITableDescribe works fine but
ODCITableFetch generates an ORA-28579
error.
I would suggest:
Look in the database server
trace directories, and the directory
where the external proc is located,
for any log or trace files generated
when the error occurs.
Instrument your external proc in
some way so that you can try to
trace its execution yourself.
Contact Oracle support
Well, an upgrade to 10.2.0.4 (was using 10.2.0.1) at least gave me an understandable error instead of a fairly useless core file and the ORA-28579.
It turns out that the code I was debugging was assuming that calling OCILobRead would return all of the data in one pass. This is the case for any client using a fixed width character set.
For clients using a variable width character set, this isn't the case, OCILobRead was actually reading part of the data and returning OCI_NEED_DATA and future calls to OCILobTrim and OCILobWrite were failing because of the still pending call to OCILobRead. The solution was to loop OCILobRead calls until OCI_NEED_DATA was no longer returned and we had all of the needed data in our buffer.
A call to OCIBreak also would have allowed the OCILobTrim and OCILobWrite functions to continue, though we wouldn't have had all of the needed input data.