Select and insert blobs as input streams using Spring's NamedParameterJdbcTemplate - spring-jdbc

Using a plain JdbcTemplate, I can do it like this
LobHandler lobHandler = new DefaultLobHandler();
InputStream inputStream= jdbcTemplate.queryForObject(
"SELECT data FROM blob_table WHERE id = ?",
new Object[]{id},
(rs, rowNum) -> lobHandler.getBlobAsBinaryStream(rs, 1)
);
jdbcTemplate.update("INSERT INTO blob_table (id, data) VALUES (?, ?)", ps -> {
ps.setString(1, id);
ps.setBinaryStream(2, inputStream);
});
but how should I do it using a NamedParameterJdbcTemplate?

This seems to work:
MapSqlParameterSource idParameter = new MapSqlParameterSource("id", id);
LobHandler lobHandler = new DefaultLobHandler();
InputStream result = jdbcTemplate.queryForObject(
"SELECT data FROM blob_table WHERE id = :id",
idParameter,
(rs, rowNum) -> lobHandler.getBlobAsBinaryStream(rs, 1)
);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("id", id);
parameters.addValue("data", inputStream);
jdbcTemplate.update("INSERT INTO blob_table (id, data) VALUES (:id, :data)", parameters);

Related

How can I get data from a stored procedure that contains a Cursor with another Cursor inside it

How can I get data from a stored procedure that contains a cursor with another cursor inside it in ASP.NET ?
When I try this code, I get the following error:
Unsupported Oracle data type RSET encountered
I need to fetch data from oracle and transfer it to a web service
Oracle 9i
This is the stored procedure and the code that I work on:
PROCEDURE P_GET_VST_CLAIMS_CLAIMSDTL ( P_PAGE_SIZE NUMBER, P_PAGE_NUMBER NUMBER, P_VST_ID NUMBER, P_PAT_ID NUMBER, P_REFCUR OUT SYS_REFCURSOR )
IS
/*
P_REFCUR_DATA STRUCTURE
----------------------------------------------------------------
VST_ID,
OL2CLAIMS_ID,
CLM_DATE,
MPTYPE_ID,
MP_TYPE_DESC_E,
MP_TYPE_DESC_A,
CLM_MP_ID,
PROVIDER_NAME_E,
PROVIDER_NAME_A,
MP_BRANCH_ID,
MP_PART_ID,
STATUS,
STATUS_DESCE,
STATUS_DESCA,
PAT_ID,
PAT_NAME_E,
PAT_NAME_A,
CLM_AMT,
CO_INS_TOT_AMT,
ATTACHS
CLAIMDTL (REFCUR)
ID NUMBER
VST_ID NUMBER
CLM_ID NUMBER
DTL_TYPE VARCHAR2
DTL_ID NUMBER
DESC_E VARCHAR2
DESC_A VARCHAR2
HCPC_ID NUMBER
MDSN_ID NUMBER
QTY NUMBER
UNIT_DESC_E VARCHAR2
UNIT_DESC_A VARCHAR2
TQ_ID NUMBER
TQ_DESC_E VARCHAR2
TQ_DESC_A VARCHAR2
REQUESTED_REPETITION NUMBER
CLM_AMT NUMBER
PRICE_LIST_AMT NUMBER
PRICE_LIST_REJ_AMT NUMBER
CO_INS_TOT_AMT NUMBER
CO_INS_DESERVED_AMT NUMBER
TPA_MP_SERVICE_AMT NUMBER
MP_DISC_AMT NUMBER
MP_NET_AMT NUMBER
*/
C# code:
[HttpPost]
[Obsolete]
public IHttpActionResult P_GET_VST_CLAIMS_CLAIMSDTL([FromBody] OracleParameters model)
{
IHttpActionResult httpActionResult;
try
{
string UsernameConfig = WebConfigurationManager.AppSettings["AppUsername"];
string PasswordConfig = WebConfigurationManager.AppSettings["AppPassword"];
if (model.AppUserName != UsernameConfig)
{
httpActionResult = this.Return_Response(false, 5, "Application Username Or Password not correct", null);
}
else if (model.AppPassword == PasswordConfig)
{
using (OracleConnection connection = new OracleConnection("Data Source= (DESCRIPTION = (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.2)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = db1))); User Id=coreapps; Password=coreapps;"))
{
OracleDataAdapter da = new OracleDataAdapter();
OracleCommand cmd = new OracleCommand()
{
Connection = connection,
CommandText = "PKG_COREAPPS.P_GET_VST_CLAIMS_CLAIMSDTL",
CommandType = CommandType.StoredProcedure
};
cmd.Parameters.Add("P_PAGE_SIZE", OracleType.Number).Value = model.P_PAGE_SIZE;
cmd.Parameters.Add("P_PAGE_NUMBER", OracleType.Number).Value = model.P_PAGE_NUMBER;
cmd.Parameters.Add("P_VST_ID", OracleType.Number).Value = model.P_VST_ID;
cmd.Parameters.Add("P_PAT_ID", OracleType.Number).Value = model.P_PAT_ID;
cmd.Parameters.Add("P_REFCUR", OracleType.Cursor).Direction = ParameterDirection.Output;
connection.Open();
OracleDataAdapter da1 = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da1.Fill(ds);
ClsLog.TextLog(ds.Tables[0].Rows[0][0].ToString());
connection.Close();
httpActionResult = this.Return_Response1(true, 1, "Success", ds);
}
}
else
{
httpActionResult = this.Return_Response(false, 5, "Application Username Or Password not correct", null);
}
}
catch (Exception exception)
{
Exception ex = exception;
ClsLog.OnError(ex);
httpActionResult = this.Return_Response(false, 3, ex.Message, null);
}
return httpActionResult;
}

How to pass parameters to Oracle DbContext FromSql in Net Core

var list = db.SomeModels.FromSql("select id from table1 where rownum < :r",10).ToList();
gives me
System.ArgumentException: 'Invalid parameter binding Parameter name: r'
What am I missing. Can't find any docs on that
The following should work:
var row = new OracleParameter("r", OracleDbType.Int32);
row.Value = 10;
var list = db.SomeModels
.FromSql("select id from table1 where rownum < :r", new object[] { row })
.ToList();
To add multiple parameters, add more OracleParameter objects to the object array:
var row = new OracleParameter("r", OracleDbType.Int32);
row.Value = 10;
var nameParameter = new OracleParameter("name", OracleDbType.Varchar2);
nameParameter.Value = "John";
var list = db.SomeModels
.FromSql("select id from table1 where rownum < :r and firstname = :name", new object[] { row, nameParameter })
.ToList();
Unfortunately, like yourself I haven't found any proper documentation for it. I will edit the answer when I do.
The following code will also work (tested with Oracle.ManagedDataAccess.Core v2.19.31 and Microsoft.EntityFrameworkCore v2.2.6):
var list = db.SomeModels
.FromSql("select id from table1 where rownum < {0}", 10)
.ToList()

is there a way to get rid of DTO

I am using Entity Framework. I have the following query in which I get data using two tables Application and Employee connected by a foreign key EmployeeID in Application Table. The tables have 1-1 relationship .
Is there a way to simplify the following code and get rid of the DTO Employee1
which is the same as auto generated Employee class
public List<Employee1> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select new Employee1
{
EmployeeID = e.EmployeeID,
SecondEmail = e.SecondEmail,
EmailID = e.EmailID,
Title = e.Title,
Name = e.Name,
Rank = e.Rank,
POBox = e.POBox,
Phone = e.Phone,
JoinDate = e.JoinDate,
Status = e.Status,
DepartmentID = e.DepartmentID.Value,
NameString = e.NameString,
Department = e.Department,
ParentDept = e.ParentDept,
DepartmentAr = e.DepartmentAr,
NameAr = e.NameAr,
NameStringAr = e.NameStringAr,
TitleAr = e.TitleAr
}).ToList();
return data;
}
If you need to return list of Employees, just select e which refers to Employee and don't use Employee1 as a DTO.
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select e).ToList();
return data;
}
Another way is this, which I would prefer because of readability:
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = context.Applications.Where(p=>p.ApplicationID == ApplicationID).Select(p=>p.Employee).ToList();
return data;
}

How to correctly return from stored procedure in Sql to model?

I need to return list of values from stored procedure to my model. How do I do it:
[HttpGet("{id}")]
public DataSource Get(int id)
{
DataSource ds = _dbContext.DataSources.Where(d => d.Id == id)
.Include(d => d.DataSourceParams)
.ThenInclude(p => p.SelectOptions).FirstOrDefault();
foreach(DataSourceParam p in ds.DataSourceParams)
{
if(p.TypeId == 5)
{
p.SelectOptions = _dbContext.SelectOptions.FromSql("Exec " + ds.DataBaseName + ".dbo." + "procGetTop50 " + ds.Id + ", 1").ToList();
}
}
return ds;
}
First, declare your procedure with parameters:
string sql = "myProcedure #param1, #param2";
Second, create parameters
var param1 = new SqlParameter { ParameterName = "param1", Value = param1Value};
var param2 = new SqlParameter { ParameterName = "param2", Value = param2Value };
Finally, exec the code:
info = this.DbContext.Database.SqlQuery<MyModel>(sql, param1, param2).FirstOrDefault();
This is it!
Just remember your model must match with the procedure columns. With means, if your procedure returns a column named 'MyProp' your model 'MyModel' must have a 'MyProp' property.

Getting error while inserting table in database?

i am inserting table in database using table datatype with the following code:
CREATE TYPE BackUpDoctorLocationAreaRoom AS TABLE (
[RoomId] bigint,
[AreaId] bigint,
[LocationId] bigint
);
Alter proc proc_tblBackUpDoctorInsert
(
#Id uniqueidentifier='',
#BackUpDoctorId uniqueidentifier='1323e1f4-7a93-4b45-9a9b-3840c32fd6d8',
#StartDate datetime='11/08/2012',
#EndDate datetime='11/09/2012',
#StartTime datetime='22:22:22',
#EndTime datetime='01:11:11',
#CreatedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#ModifiedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#createdDate datetime='11/6/12 3:09:58 AM',
#ModifiedDate datetime='11/6/12 3:09:58 AM',
#tblBackUpDoctorsForRooms BackUpDoctorLocationAreaRoom READONLY
)
as
set xact_abort on
declare #newId uniqueidentifier;
set #newId = newid();
insert into tblBackUpDoctor (Id,BackUpDoctorId,StartDate,EndDate,StartTime,EndTime,CreatedBy,ModifiedBy,
createdDate,ModifiedDate,IsActive,isdeleted) values
(#newId,
#BackUpDoctorId,
#StartDate,
#EndDate,
#StartTime,
#EndTime,
#CreatedBy,
#ModifiedBy,
#createdDate,
#ModifiedDate,
1,0)
declare #IdFortblBackUpDoctorsForRooms uniqueidentifier;
set #IdFortblBackUpDoctorsForRooms = newid();
delete from tblBackUpDoctorsForRooms where BackUpRecordId=#id and Roomid in (Select roomid from #tblBackUpDoctorsForRooms)
delete from tblbackupdoctor where id=#id
insert into tblBackUpDoctorsForRooms (BackUpRecordId,Roomid,Araeid,locationid)
Select #newId,roomid,areaid,locationid from #tblBackUpDoctorsForRooms
select #newId
This is the sp in which i am using that table.
My class file's code is :
public string InsertBackUpDoctor(ClsBackUpDoctorProp objProp, DataTable dtLocAreaRoom)
{
String ConnectionString = CCMMUtility.GetCacheForWholeApplication();
String backUpRecordId = "";
SqlParameter[] param = new SqlParameter[12];
param[0] = new SqlParameter("#Id", objProp.Id);
param[1] = new SqlParameter("#BackUpDoctorId", objProp.BackUpDoctorId);
param[2] = new SqlParameter("#StartDate", objProp.StartDate);
param[3] = new SqlParameter("#EndDate", objProp.EndDate);
param[4] = new SqlParameter("#StartTime", objProp.StartTime);
param[5] = new SqlParameter("#EndTime", objProp.EndTime);
param[6] = new SqlParameter("#CreatedBy", objProp.CreatedBy);
param[7] = new SqlParameter("#ModifiedBy", objProp.ModifiedBy);
param[8] = new SqlParameter("#createdDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[9] = new SqlParameter("#ModifiedDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[10] = new SqlParameter("#CurrentDate", objProp.CurrentDate);
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString, "proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();
return backUpRecordId;
}
and here is the error which is coming when i tries to insert :
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 12 ("#tblBackUpDoctorsForRooms"), row 0, column 0: Data type 0xF3 (user-defined table type) has a non-zero length database name specified. Database name is not allowed with a table-valued parameter, only schema name and type name are valid.
I dont know why this coming please help me..
I believe you'd have to change the way you pass your custom parameter:
Not just
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
but rather something like
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#tblBackUpDoctorsForRooms";
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
parameter.Value = dtLocAreaRoom;
param[11] = parameter;
try
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
and in the call add
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString,CommandType.StoredProcedure
"proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();

Resources