In groovy how can i use sql executeQuery method. In my below code i get the error as "Method executeQuery is protected in groovy.sql.Sql" on line 2. Please help!
def sql = new Sql(rdbDsService.getDataSource())
ResultSet rs=sql.executeQuery("select top 5 Id from MACHINES where (Total != Rightcount) order by FinishingTime");
order[0] = 0;
order[1] = 0;
order[2] = 0;
order[3] = 0;
count = 0;
while (rs.next())
{
order[count] = Integer.parseInt(rs["Id"].toString());
count = count + 1;
}
As per the message you're calling a protected method, the javadoc on the method states the following:
Useful helper method which handles resource management when executing
a query which returns a result set. Derived classes of Sql can
override "createQueryCommand" and then call this method to access the
ResultSet returned from the provided query or alternatively can use
the higher-level method of Sql which return result sets which are
funnelled through this method, e.g. eachRow, query.
Instead try using something like eachRow
sql.eachRow("select top 5 Id from MACHINES where (Total != Rightcount) order by FinishingTime") {
order[count] = it.Id
count = count + 1
}
Related
Domain class:
class Transaction {
String roundId
BigDecimal amount
:
}
The SQL we wish to execute the following:
"select sum(t.amount) from transaction t where t.roundId = xxx"
We have been unable to find an example which does not return Transaction rows.
We assume there are two approaches:
Use projections and/or criteria etc? All the examples we have found only return lists of transaction rows, not the sum.
Use raw SQL. How do we call SQL, and get a handle on the BigDecimal it returns?
I tried this:
class bla{
def sessionFactory
def someMethod() {
def SQLsession = sessionFactory.getCurrentSession()
def results = SQLsession.createSQLQuery("select sum(t.credit) from transaction t where t.round_id = :roundId", [roundId: roundId])
But this fails with
groovy.lang.MissingMethodException: No signature of method: org.hibernate.internal.SessionImpl.createSQLQuery() is applicable for argument types: (java.lang.String, java.util.LinkedHashMap)
Also, I have no idea what the return type would be (cant find any documentation). I am guessing it will be a list of something: Arrays? Maps?
==== UPDATE ====
Found one way which works (not very elegant or grails like)
def SQLsession = sessionFactory.getCurrentSession()
final query = "select sum(t.credit) from transaction t where t.round_id = :roundId"
final sqlQuery = SQLsession.createSQLQuery(query)
final results = sqlQuery.with {
setString('roundId', roundId)
list() // what is this for? Is there a better return value?
}
This seems to return an array, not a list as expected, so I can do this:
if (results?.size == 1) {
println results[0] // outputs a big decimal
}
Strangely, results.length fails, but results.size works.
Using Criteria, you can do
Transaction.withCriteria {
eq 'roundId', yourRoundIdValueHere
projections {
sum 'amount'
}
}
https://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/classic/Session.html
Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses)
Query createSQLQuery(String sql, String returnAlias, Class returnClass)
The second argument of createSQLQuery is one or more returnAliases and not meant for binding the statement to a value.
Instead of passing your values in the 2nd argument, use the setters of your Query object i.e. setString, setInteger, etc.
results.setInteger('roundId',roundId);
So I have a standard service reference proxy calss for MS CRM 2013 (i.e. right-click add reference etc...) I then found the limitation that CRM data calls limit to 50 results and I wanted to get the full list of results. I found two methods, one looks more correct, but doesn't seem to work. I was wondering why it didn't and/or if there was something I'm doing incorrectly.
Basic setup and process
crmService = new CrmServiceReference.MyContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var accountAnnotations = crmService.AccountSet.Where(a => a.AccountNumber = accountNumber).Select(a => a.Account_Annotation).FirstOrDefault();
Using Continuation (something I want to work, but looks like it doesn't)
while (accountAnnotations.Continuation != null)
{
accountAnnotations.Load(crmService.Execute<Annotation>(accountAnnotations.Continuation.NextLinkUri));
}
using that method .Continuation is always null and accountAnnotations.Count is always 50 (but there are more than 50 records)
After struggling with .Continutation for a while I've come up with the following alternative method (but it seems "not good")
var accountAnnotationData = accountAnnotations.ToList();
var accountAnnotationFinal = accountAnnotations.ToList();
var index = 1;
while (accountAnnotationData.Count == 50)
{
accountAnnotationData = (from a in crmService.AnnotationSet
where a.ObjectId.Id == accountAnnotationData.First().ObjectId.Id
select a).Skip(50 * index).ToList();
accountAnnotationFinal = accountAnnotationFinal.Union(accountAnnotationData).ToList();
index++;
}
So the second method seems to work, but for any number of reasons it doesn't seem like the best. Is there a reason .Continuation is always null? Is there some setup step I'm missing or some nice way to do this?
The way to get the records from CRM is to use paging here is an example with a query expression but you can also use fetchXML if you want
// Query using the paging cookie.
// Define the paging attributes.
// The number of records per page to retrieve.
int fetchCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Initialize the number of records.
int recordCount = 0;
// Define the condition expression for retrieving records.
ConditionExpression pagecondition = new ConditionExpression();
pagecondition.AttributeName = "address1_stateorprovince";
pagecondition.Operator = ConditionOperator.Equal;
pagecondition.Values.Add("WA");
// Define the order expression to retrieve the records.
OrderExpression order = new OrderExpression();
order.AttributeName = "name";
order.OrderType = OrderType.Ascending;
// Create the query expression and add condition.
QueryExpression pagequery = new QueryExpression();
pagequery.EntityName = "account";
pagequery.Criteria.AddCondition(pagecondition);
pagequery.Orders.Add(order);
pagequery.ColumnSet.AddColumns("name", "address1_stateorprovince", "emailaddress1", "accountid");
// Assign the pageinfo properties to the query expression.
pagequery.PageInfo = new PagingInfo();
pagequery.PageInfo.Count = fetchCount;
pagequery.PageInfo.PageNumber = pageNumber;
// The current paging cookie. When retrieving the first page,
// pagingCookie should be null.
pagequery.PageInfo.PagingCookie = null;
Console.WriteLine("#\tAccount Name\t\t\tEmail Address");while (true)
{
// Retrieve the page.
EntityCollection results = _serviceProxy.RetrieveMultiple(pagequery);
if (results.Entities != null)
{
// Retrieve all records from the result set.
foreach (Account acct in results.Entities)
{
Console.WriteLine("{0}.\t{1}\t\t{2}",
++recordCount,
acct.EMailAddress1,
acct.Name);
}
}
// Check for more records, if it returns true.
if (results.MoreRecords)
{
// Increment the page number to retrieve the next page.
pagequery.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
pagequery.PageInfo.PagingCookie = results.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}
I am looking for a way to return the value of a precise column in the first result of a query.
The query result contains always 1 row containing the following columns :
ID
PW
RANK
I am trying to only get the rank value in order to push it into a session variable.
I tried messing with :
$row-> $query->row();
But then I don't know how to get only the value of the rank column. Ideally, I would want to get that value, then return it to allow my controller to set it in the session variable ( doing it in the model would be easier but would break the MVC pattern, right ?)
How can I do this ?
Thanks
Have the controller call a function in the model that return that value. Let's say the model has a function name get_rank()
public function get_rank($id)
{
// assumes your ID is an int
$id = (int)$id;
// avoid wasting a query
if ($id < 1) return FALSE;
// build query
$this->db->select('rank');
$this->db->from('YOUR_TABLE');
$this->db->where('id', $id);
// maybe some sorting / limiting here if you need it
// get result
$rs = $this->db->get();
if ($rs->num_rows() > 0)
{
// just get the first row
$row = $rs->row();
return $row->rank;
}
return FALSE;
}
I am new to NHibernate and I want to have a count of rows from database. Below is my code,
SearchTemplate template = new SearchTemplate();
template.Criteria = DetachedCriteria.For(typeof(hotel));
template.Criteria.Add(Restrictions.Lt("CheckOutDate", SelDate) || Restrictions.Eq("CheckOutDate", SelDate));
template.Criteria.Add(Restrictions.Eq("Canceled", "False"));
int count = template.Criteria.SetProjection(Projections.Count("ID"));
It gives me an error when I try to compile app that says
"Cannot implicitly convert type 'NHibernate.Criterion.DetachedCriteria' to 'int'"
I want to have a count of rows of the table hotel..
You want to use GetExecutableCriteria:
SearchTemplate template = new SearchTemplate();
template.Criteria = DetachedCriteria.For(typeof(hotel));
template.Criteria.Add(Restrictions.Lt("CheckOutDate", SelDate) || Restrictions.Eq("CheckOutDate", SelDate));
template.Criteria.Add(Restrictions.Eq("Canceled", "False"));
var count = DoCount(template.Criteria, session /* your session */);
public long DoCount(DetachedCriteria criteria, ISession session)
{
return Convert.ToInt64(criteria.GetExecutableCriteria(session)
.SetProjection(Projections.RowCountInt64())
.UniqueResult());
}
On a side note, you should take a look at using NHibernate.Linq:
var result = (from h in Session.Linq<Hotel>()
where h.CheckOutDate <= SelDate
where h.Canceled != true
select h).Count();
More information here.
I´m using the LinqDataSource to populate a grid. But now I need the SQL query that the LinqDataSource generates, to pass around throught methods (no, I can't modify the methods to not need a SQL query).
Is there a way to obtain the generated SQL query from a instantiated and configured LinqDataSource?
Hope this helps.
using the function below will return a SqlQueryText
you can rebuild the query from that object.
to get the sql text you can use use the .Text Property
to get the passed
parameters you can use the .Params property
public static SqlQueryText GetFullQueryInfo(DataContext dataContext, IQueryable query)
{
DbCommand dbCommand = dataContext.GetCommand(query);
var result = new SqlQueryText();
result.Text = dbCommand.CommandText;
int nParams = dbCommand.Parameters.Count;
result.Params = new ParameterText[nParams];
for (int j = 0; j < nParams; j++)
{
var param = new ParameterText();
DbParameter pInfo = dbCommand.Parameters[j];
param.Name = pInfo.ParameterName;
param.SqlType = pInfo.DbType.ToString();
object paramValue = pInfo.Value;
if (paramValue == null)
{
param.Value = null;
}
else
{
param.Value = pInfo.Value.ToString();
}
result.Params[j] = param;
}
return result;
}
here is an example
var results = db.Medias.Where(somepredicatehere);
ClassThatHasThisMethod.GetFullQueryInfo(yourdatacontexthere, results);
EDIT:
Sorry forgot to include the SqlQueryText data structures
public struct SqlQueryText
{
public ParameterText[] Params;
public string Text;
}
public struct ParameterText
{
public string Name;
public string SqlType;
public string Value;
}
You can run SQL Profiler while running your application and that should give it to you.
Take a look at LinqPad for debugging and to understand how it works. But if you want it at run-time, I think you're out of luck.
The Sql will only be generated by the Linq to Sql infrastructure at runtime.
I think there are some tools to see generated Sql in the debugger, but if you don't plan to use linq to generate your Sql dynamicaly, shouldn't you probably look for a simple Sql designer ?
I Found a Linq To Sql Debug visualizer on Scottgu's blog.