How is it better to send data using Dapper in c# to PL/SQL scripts variables of RECORD type

一世执手 提交于 2019-12-11 16:24:17

问题


I have a PL/SQL procedure that using 3 variables of RECORD type as parameters, which i have to fill with my data (from c# application) to execute a procedure.

1st i've tried to build the same structure with this records via c# and pass as a parameter via Dapper, but it's not working since dapper works only with scalar data types.

Then i've tried to pass my data as arrays and to map them inside the procedure, but RECORD type can't accept sets of data like a.NAME := ('aaaaaa','sdasd'); it works only this way:

a.NAME(1) := 'aaaaaa';
a.NAME(2) := 'sdasd';

The only thing that i have on my mind now is to generate such strings in the procedure text, but i'm feeling like there should be a better way. What am doing wrong?

P.S. i can't change the script that needs to be running after all, so i can't change the data type it accepts.

Update: To make it easier, let's say, i've decided to make an example:

We have 2 custom types

TYPE A_REC IS RECORD (NAME dbms_sql.Varchar2_Table);
TYPE B_REC IS RECORD (NAME dbms_sql.Varchar2_Table
                         , ID dbms_sql.Number_Table);

and a procedure, which might be used something like

declare
a c_pck.a_rec;
b c_pck.b_rec;
begin

a.NAME(1) := 'aaaaa';
b.NAME(1) := 'sssss';
b.NAME(2) := 'ddddd';
b.ID(1) := 111;
b.ID(2) := 222;


c_pck.pr(a => a, b => b);
end;

How can i run this procedure via Dapper?


回答1:


I am not 100% sure if this will work for PL\SQL, however you can pass in SQL Table Value Parameters into a stored procedure that you call from Dapper. RECORD types sound like the same thing so it may work.

You need to use a DataTable to construct your RECORD. The order of the columns that you define must match the same order that they appear in your database.

From the below link:

var dt = new DataTable();
dt.Columns.Add("AUDIT_PK", typeof (long));
dt.Columns.Add("MESSAGE", typeof (string));
dt.Columns.Add("SUCCESS", typeof (bool));
dt.Rows.Add(1, "EHLO", null);

using (var conn = new SqlConnection("Data Source=.;Initial  Catalog=Scratch;Integrated Security=true"))
{
    conn.Open();
    conn.Execute("TestOne", new {TVP =   dt.AsTableValuedParameter("dbo.AUDITRECORD")}, commandType: CommandType.StoredProcedure);
}

https://www.codeproject.com/Articles/835519/Passing-Table-Valued-Parameters-with-Dapper




回答2:


You need to handle two separate things here.

  1. Instruct the Oracle driver about your custom data types

Here, you're going to need a fair amount of boilerplate. You have to write mapping code for your UDTs, using the IOracleCustomType interface. Here's the official documentation. This guide seems like a good resource.

  1. Instruct Dapper about your custom data types

Dapper has a hard-coded list of .NET types mapped to DbTypes. You can add to this list, but only to the generic DbTypes. To use database specific functionality, your parameter must implement SqlMapper.ICustomQueryParameter (this is how the Table-valued stuff for SQL server works). In your AddParameter implementation, you can manually construct an OracleParameter and set the UDT typename correctly. The return value should be handled just fine by Dapper, since this is just mapping a result set like



来源:https://stackoverflow.com/questions/49739027/how-is-it-better-to-send-data-using-dapper-in-c-sharp-to-pl-sql-scripts-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!