StoredProcItemReader- procedure is returning two resultset - stored-procedures

I am using StoredProcItemReader in spring batch and my storedProcedure is returning two resultset. How can i get the result from both resultset in a single go/call. Can i set storedProcItemReader.setRefCursorPosition(<<1st resultset index>>) and storedProcItemReader.setRefCursorPosition(<<2nd resultset index>>) both.
As we can get the two resultset's result in normal java jdbc call like:-
CallableStatement cStmt = myConnect.prepareCall("{CALL sp_emps_in_dept(?)}");
cStmt.setInt(1, deptId);
cStmt.execute();
ResultSet rs1 = cStmt.getResultSet();
while (rs1.next())
{
// Result
}
rs1.close();
/* process second result set */
if (cStmt.getMoreResults())
{
ResultSet rs2 = cStmt.getResultSet();
while (rs2.next())
{
// 2nd Result
}
rs2.close();
}
cStmt.close();

You'll need a custom ItemReader for this. Spring Batch's StoredProcedureItemReader only supports reading from a single ResultSet.

Related

How to get multiple RecordSets from StoredProcedure with NReco.Data in Asp.NetCore

I use NReco.Data in my Asp.NetCore Application to make db-calls, because I don't want to use EF and DataTable isn't supported yet.
Now I need to call a StoredProcedure and get Multiple RecordSets (or Dictionarylists).
At the moment I called this:
dbAdapter.Select($"STOREDNAME #{nameof(SQLPARAMETER)}", SQLPARAMETER).ToRecordSet()
But the stored gives me more than 1 recordset, can anyone help me to get the others?
Currently NReco.Data.DbDataAdapter has no API for processing multiple result sets returned by single IDbCommand.
You can compose IDbCommand by yourself, execute data reader and read multiple result sets in the following way:
IDbCommand spCmd; // lets assume that this is DB command for 'STOREDNAME'
RecordSet rs1 = null;
RecordSet rs2 = null;
spCmd.Connection.Open();
try {
using (var rdr = spCmd.ExecuteReader()) {
rs1 = RecordSet.FromReader(rdr);
if (rdr.NextResult())
rs2 = RecordSet.FromReader(rdr);
}
} finally {
spCmd.Connection.Close();
}
As NReco.Data author I think that support for multiple result sets may be easily added to DbDataAdapter API (I've just created an issue for that on github).
-- UPDATE --
Starting from NReco.Data v.1.0.2 it is possible to handle multiple result sets in the following way:
(var companies, var contacts) = DbAdapter.Select("exec STOREDNAME").ExecuteReader(
(rdr) => {
var companiesRes = new DataReaderResult(rdr).ToList<CompanyModel>();
rdr.NextResult();
var contactsRes = new DataReaderResult(rdr).ToList<ContactModel>();
return (companiesRes, contactsRes);
});
In the same manner DataReaderResult can map results to dictionaries or RecordSet if needed.

Stored Procedure with dapper.net is slower than EF

I have been replacing Entity Framework and LINQ queries with dapper.net as a means of data access with great success, I am seeing real improvements in speed. However when I try the same with a stored procedure, the result is the opposite, I get a Timeout expired error every time:
The stored procedure itself is unchanged so it's clearly not the issue, suffice to say it returns 2 result sets: data and a rowcount. It is used to populate a jquery datatable. This is the code used to call the proc:
public DapperQueryMultipleModel GetStockCatalogueDatatable_WIP(DatatableFilterModel model)
{
DapperQueryMultipleModel returnModel = new DapperQueryMultipleModel();
var p = new DynamicParameters();
p.Add("#storeId", model.Store);
// more params..
p.Add("#TotalRowsCount", dbType: DbType.Int32, direction: ParameterDirection.Output);
using (var connection = _context.Database.Connection)
{
using (var multi = connection.QueryMultiple("dbo.StockCatalogueDatatable", p, commandType: CommandType.StoredProcedure))
{
returnModel.TableData = multi.Read<dynamic>().ToList();
returnModel.RowCount = multi.Read<int>().Single();
}
}
return returnModel;
}
Am I doing something wrong?

How to use SearchCount method of Search Service Interface of atlassian 6.2.1?

I am developing application related to jira. I want count of issues return by the jql query.
i got searchCount method in this link but i am not getting how to use this method using instance.
The setup should look like this:
String jqlQuery = "project=ABC"; // insert your JQL query here
SearchService.ParseResult parseResult = searchService.parseQuery(currentUser, jqlQuery);
if (!parseResult.isValid())
{
// errors in parseResult.getErrors().getErrorMessages()
throw new MyException();
}
com.atlassian.query.Query query = parseResult.getQuery();
com.atlassian.jira.util.MessageSet validateResults = searchService.validateQuery(currentUser, query);
if (validateResults.hasAnyErrors())
{
// errors in validateResults.getErrorMessages()
throw new MyException();
}
With the resulting validated query object, you can then call searchService.searchCount(currentUser, query) to get your issue count.

Breeze not returning observables when .select() clause is used

This is the method that calls the controller for CustomerStrings entries:
var getCustStrings = function (custStrings, custId) {
var query = EntityQuery.from('CustomerStrings')
.where('CustomerID', '==', custId)
.select('CustomerStringNumber, CustomerString1')
.orderBy('CustomerStringNumber');
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
if (custstrings){
console.log(data.results);
custstrings(data.results);
}
console.log('Retrieved [CustomerStrings] from remote data source');
}
};
The problem is that if I use .select(...) clause the returned objects are plain javascript objects, when I'm expecting them to be dependentobservables.
If I remove the .select() clause the returned result is right.
Any solutions?
That is exactly how the select clause works. If you would like to map the returned DTOs back to your entities just add a toType('') clause to your query
var query = entityQuery
.from('CustomerStrings')
.where(something)
.select(whatever)
.toType('CustomerStrings');

Execute raw SQL query in ASP.NET MVC, database first mode

The model of my project is database first, and uses remote access to database on another server.
I need to use raw SQL query because my query is very complex and I feel more comfortable in SQl not LINQ.
This is how I do:
string query = "select * from Inquiry_TBL where ...";
using (educationEntities db = new educationEntities())
{
var list = db.Database.SqlQuery<Inquiry_TBL>(query);
ViewData["total"] = list.Count();
}
The problem is sometimes I get the query result within a second, sometimes it just keep loading for a long time and gives me an error that 'Calling 'Read' when the data reader is closed is not a valid operation.'
Why is that? Is there something wrong with my code, or because I'm using remote access to another server? Will switching to local server solve the problem?
The Entity Framework Code First API includes methods that enable you to pass SQL commands directly to the database. You have the following options:
• Use the DbSet.SqlQuery method for queries that return entity types. The returned objects must be of the type expected by the DbSet object, and they are automatically tracked by the database context unless you turn tracking off. (See the following section about the AsNoTracking method.)
• Use the Database.SqlQuery method for queries that return types that aren't entities. The returned data isn't tracked by the database context, even if you use this method to retrieve entity types.
• Use the Database.ExecuteSqlCommand for non-query commands.
Calling a Query that Returns Entities:
public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// Commenting out original code to show how to use a raw SQL query.
//Department department = await db.Departments.FindAsync(id);
// Create and execute raw SQL query.
string query = "SELECT * FROM Department WHERE DepartmentID = #p0";
Department department = await db.Departments.SqlQuery(query, id).SingleOrDefaultAsync();
if (department == null)
{
return HttpNotFound();
}
return View(department);
}
Calling a Query that Returns Other Types of Objects:
public ActionResult About()
{
//Commenting out LINQ to show how to do the same thing in SQL.
//IQueryable<EnrollmentDateGroup> = from student in db.Students
// group student by student.EnrollmentDate into dateGroup
// select new EnrollmentDateGroup()
// {
// EnrollmentDate = dateGroup.Key,
// StudentCount = dateGroup.Count()
// };
// SQL version of the above LINQ code.
string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
+ "FROM Person "
+ "WHERE Discriminator = 'Student' "
+ "GROUP BY EnrollmentDate";
IEnumerable<EnrollmentDateGroup> data = db.Database.SqlQuery<EnrollmentDateGroup>(query);
return View(data.ToList());
}
Calling an Update Query:
[HttpPost]
public ActionResult UpdateCourseCredits(int? credit)
{
if (credit != null)
{
ViewBag.RowsAffected = db.Database.ExecuteSqlCommand(
"UPDATE Course SET Credits = Credits * {0}", credit);
}
return View();
}
For more information have a look at Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application (12 of 12).

Resources