Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PLSQL Record type support for associative arrays #275

Open
gpgpublickey opened this issue Jan 17, 2023 · 8 comments
Open

PLSQL Record type support for associative arrays #275

gpgpublickey opened this issue Jan 17, 2023 · 8 comments

Comments

@gpgpublickey
Copy link

gpgpublickey commented Jan 17, 2023

In the following scenario:

Stored procedures or functions trying to pass table valued parameters / associative arrays / PL/SQL Index-By Tables are not supporting the PLSQL RECORD type, many applications use this strategy to use multidimensional arrays, currently the ODP.NET Core is not able to work with this kind of associative arrays.

Real world problem:
Use plsql records in combination of associative arrays is really often common strategy used in PLSQL to handle data, so each time you found something like this (and is very common to found) you will need to write wrappers into db or modify existing sp's or functions (something that is not always possible depending on project constraints)

Is there any expected date to implement the support for RECORDS or any well known workaround to make possible use ODP.NET Core in this scenario?

@alexkeh
Copy link
Member

alexkeh commented Jan 17, 2023

This feature cannot be used today unless the RECORD is changed into some other type, such as a custom user-defined type.

There hasn't been too many customer requests for this feature. If developers vote for this feature, the Oracle .NET team will look closer at implementing native ODP.NET RECORD data type support.

@gpgpublickey
Copy link
Author

gpgpublickey commented Jan 17, 2023

Hi @alexkeh any recommended approach regarding this replacement of RECORD to an UDT type? I can't modify the original SPs because of backward compatibility, so I will need to go with a wrapper. But would like to hear recommended strategies to parse the RECORD into an OBJECT and viceversa.

Where is possible to vote for this request? is any existent request for it?

@alexkeh
Copy link
Member

alexkeh commented Jan 17, 2023

Developers can give a thumbs up to the original request you made up top to vote for the request. You'll see this commonly used with other ODP.NET and .NET feature requests. People can also comment on the thread on their own need as well to provide added detail on their need and their preferences. Here's the current Oracle .NET GitHub issue list organized by thumbs up votes.

This Oracle forum thread on using RECORDs with ODP.NET provide more details on possible workarounds. Unmanaged ODP.NET was available at the time, but the general advice applies to ODP.NET Core even today. Using a wrapper is one of the possible workarounds.

@gpgpublickey
Copy link
Author

gpgpublickey commented Jan 18, 2023

In order to look for a workaround, I decided to go with a wrapper, so now I'm trying to return a nested array of an UDT object, the command is input/output direction.
But when I try to execute it I get a System.InvalidCastException: Column contains NULL data

But the UDT type defined in my c# class it has just string types, same in my UDT type in db,
create or replace TYPE FOO_TYPE AS OBJECT ( my_foo_bar VARCHAR2(20));

Any idea why I'm getting such kind of error? I'm trying to follow the nested types with UDT docs example, but in a different way since I need an input/output scenario.
cc: @alexkeh any advise here? or maybe something to tag in order to help?

Thx

@alexkeh
Copy link
Member

alexkeh commented Jan 18, 2023

There are additional ODP.NET UDT samples on GitHub.

The Oracle Developer Tools for Visual Studio has an UDT custom class code generation wizard to make it easy to set up and use UDTs in .NET.

@gpgpublickey
Copy link
Author

gpgpublickey commented Jan 18, 2023

Yes I was using the examples there, but nothing similar for my scenario, I will give a try to the VS Oracle dev tools to see if that solve my issue.
Thanks, I would like to suggest add an example of input/output parameters for nested + UDTs. Thanks

@gpgpublickey
Copy link
Author

gpgpublickey commented Jan 19, 2023

I'm able to retrieve it correctly using the auto generated udt types created with the oracle developer tools extension for visual studio, thanks for the support!

I will explain here what workaround I decided to follow and why:

I found mostly two recommended approaches in many topics in forums, blogs, etc. The main problem as is described in the first post on this issue is lack of native support of PLSQL RECORD type in data providers (not just odp.net, i didn't found providers supporting this plsql special type).
The workarounds are:
1- db wrapper + sys_refcursors
2- db wrapper + nested array + UDT type

Option 1- Is just a good option if your procedure or function needs to support just OUTPUT / RETURN way, since is not posible to send sys_refcursors as INPUTs from ODP.NET, at least I didn't found an intermediate complexity level to go through that vs time efforts.

Option 2- Use a wrapper replacing the associative array for a nested array, and replace the PLSQL Record type by an UDT type, aditionally, you can add an extra parameter to receive the original RECORD type in your wrapper, since is possible to write raw sql to declare and define the record type as part of the Command configuration with ODP.NET, so you can send the RECORD type with any required data, pass it to the original functionality and then parse the result to the UDT nested array as part of your wrapper body implementation.
I didn't check this approach with functions, but for functions probably option 1 is easier to use since you don't need to be worried about INPUT / OUTPUT parameters, you can build the record type in a declare block in you client class, then get the result as a sys_refcursor, but option 2 is something to have in mind if you want something more object oriented.

Hope this will help somebody in the future ) have a nice day!

@christianshay
Copy link
Member

christianshay commented Jun 6, 2023

Careful with using UDTs unneccesarily. There can be performance implications. Make you evaluate the performance and make sure it scales as you need it. In performance sensitive use cases I would not use them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants