Print Thread
CLOBs using C++ Builder
#64757 08/11/23 04:11 AM
Joined: Jul 2005
Posts: 11
Tulsa, OK
S
Stephen Offline OP
Member
OP Offline
Member
S
Joined: Jul 2005
Posts: 11
Tulsa, OK
I see lots of examples using Delphi but non for C++ Builder with the temporary LOB (CreateTemporary) calls.

I don't even know if that's what I need to do....

I have an Oracle function inside a package:
SQL Query
function my_func(pJSON in clob) returning clob is
  cRetval clob := empty_clob();
begin
  cRetval := 'some long text value in JSON format';
  return cRetval;
end;

I use the Package Wizard to create components for each of my packages.

I want to call this function from C++ Builder, passing in a CLOB and receiving a CLOB in return.

Code that was working (but not with 11.3):
Code

TLOBLocator *inp = new TLOBLocator(OraSession, otCLOB, true);
inp->AsString = "some JSON input string";

TLOBLocator *outp = MyPackage->MyFunc(inp);      // <<- crash here
ShowMessage(outp->AsString);

delete outp;
delete inp;

Any help (with examples) would be greatly appreciated!

Last edited by Stephen; 08/11/23 04:12 AM.
Re: CLOBs using C++ Builder
Stephen #64758 08/11/23 08:59 AM
Joined: Aug 1999
Posts: 22,206
Member
Offline
Member
Joined: Aug 1999
Posts: 22,206
Can you show me the pascal source of the MyPackage.MyFunc function?


Marco Kalter
Allround Automations
Re: CLOBs using C++ Builder
Stephen #64760 08/11/23 12:26 PM
Joined: Jul 2005
Posts: 11
Tulsa, OK
S
Stephen Offline OP
Member
OP Offline
Member
S
Joined: Jul 2005
Posts: 11
Tulsa, OK
SQL Query
function TMyPackage.my_func(Pjson: TLOBLocator): TLOBLocator;
begin
  Result := TLOBLocator.Create(Session, otCLOB);
  ThreadAcquire;
  try
    GetQuery;
    OCPQuery.DeclareVariable('function_result', otCLOB);
    OCPQuery.SetComplexVariable('function_result', Result);
    OCPQuery.DeclareVariable('PJSON', otCLOB);
    OCPQuery.SetComplexVariable('PJSON', Pjson);
    OCPQuery.SQL.Add('begin');
    OCPQuery.SQL.Add('  :function_result := "MYPACKAGE_PAKG"."MY_FUNC"(PJSON => :PJSON);');
    OCPQuery.SQL.Add('end;');
    OCPQuery.Execute;
  except
    ThreadRelease;
    Result.Free;
    raise;
  end;
  ThreadRelease;
end;

I can replicated this function by creating the query and declaring the parameters without a problem. The issue is when I try to call it from within the component that is created by the wizard.

Interestingly enough, if I modify the call (from the initial post) where I'm not even looking at the return value such as:
Code
MyPackage->MyFunc(inp);      // <<- crash here

I still receiver the error ORA-03120: two-task conversion routine: integer overflow. When I look up this error, I get the response that it is usually generated from the calling program. I can run the stored procedure all day long using the CLOB I'm passing in to the function and I've verified that it indeed has a value when I'm passing it in.

Also, it works just fine when I replicate the code above where I create the query, the 2 TLOBLocators and declare and set everything.

Last edited by Stephen; 08/11/23 03:27 PM.
Re: CLOBs using C++ Builder
Stephen #64761 08/14/23 08:37 AM
Joined: Aug 1999
Posts: 22,206
Member
Offline
Member
Joined: Aug 1999
Posts: 22,206
Can you change

Result := TLOBLocator.Create(Session, otCLOB);

to

Result := TLOBLocator.CreateTemporary(Session, otCLOB, True);

and try again?


Marco Kalter
Allround Automations

Moderated by  support 

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.4
(Release build 20200307)
Responsive Width:

PHP: 7.1.33 Page Time: 0.025s Queries: 15 (0.007s) Memory: 2.5154 MB (Peak: 3.0393 MB) Data Comp: Off Server Time: 2024-04-29 16:04:13 UTC
Valid HTML 5 and Valid CSS