MyBatis doesn't return all the results from the query - sql

The Problem
I have a query that returns 17 records. When I use MyBatis with a map that has an <association> it returns 6 records. Note that this doesn't happen with my other maps, I have many other maps with associations that all work fine.
Query:
with leave_counts as
(
select leave_type_id, count(llm.leave_id) as count
from lw_leave_master llm
group by leave_type_id
)
select llt.leave_type_id, llt.leave_type_abbr_tx,
llt.leave_type_desc_tx, lc.count as count_nm
from lw_leave_type llt
join leave_counts lc on lc.leave_type_id=llt.leave_type_id
order by llt.leave_type_abbr_tx
Map:
<resultMap id="typeCountMap" type="mypackage.myclass">
<result property="count" column="count_nm"/>
<association property="type" resultMap="package.myMap"/>
</resultMap>
<resultMap id="myMap" type="mypackage.myclass2">
<result property="id" column="leave_type_id"/>
<result property="abbr" column="leave_type_abbr_tx"/>
<result property="description" column="leave_type_desc_tx"/>
</resultMap>
The <association> in typeCountMap refers to the map myMap.
This returns 6 records every time. Grabbing the actual query run from the logger and running it manually returns 17 records.
Solutions?
There are two things I can do to get MyBatis to return all 17 records
#1
If I remove the lc.count as count_nm from my query I get all 17 records returned (just with no values associated with them)
with leave_counts as
(
select leave_type_id, count(llm.leave_id) as count
from lw_leave_master llm
group by leave_type_id
)
select llt.leave_type_id, llt.leave_type_abbr_tx,
llt.leave_type_desc_tx
from lw_leave_type llt
join leave_counts lc on lc.leave_type_id=llt.leave_type_id
order by llt.leave_type_abbr_tx
This is obviously not a good solution, but I wanted to include this in case it would help you figure out what I'm doing wrong.
#2
If I replace the association with the contents of the other map everything works as expected.
<resultMap id="typeCountMap" type="mypackage.myclass1">
<result property="count" column="count_nm"/>
<result property="type.id" column="leave_type_id"/>
<result property="type.abbr" column="leave_type_abbr_tx"/>
<result property="type.description" column="leave_type_desc_tx"/>
</resultMap>
This obviously is what I'll do if I don't find another solution, since this does work. It would just be nice to use the <association> like I have in other maps.
I should note that I am using MyBatis 3.1.1

I recently ran into this same problem. I believe the issue was related to my main resultMap with the association in it not having an id column while my association's resultMap did have an id column. My results were getting grouped by the associations id column.
To correct the issue I selected the row number in my query and added an id to my main resultMap pointing to the row number column.

If you're using 3.1.1 you can define just <id column="leave_type_id" /> without property attribute
If you're not using 3.1.1 you can add <result property="abbr" column="leave_type_id" /> on top of the list to include field into cache key calculation for association, later re-definition will assign correct value

I don't know if this is the problem, but it's something to try. I have to post here because I don't have enough rep to leave a comment.
Try adding a column attribute to your association and marking the ID column in the second map:
<resultMap id="typeCountMap" type="mypackage.myclass">
<result property="count" column="count_nm"/>
<association property="type" column="leave_type_id" resultMap="package.myMap"/>
</resultMap>
<resultMap id="myMap" type="mypackage.myclass2">
<id property="id" column="leave_type_id"/>
<result property="abbr" column="leave_type_abbr_tx"/>
<result property="description" column="leave_type_desc_tx"/>
</resultMap>

You should replace the line <result property="id" column="leave_type_id"/>
with <id property="id" column="leave_type_id"/>.
In mybatis you should not miss to specify the id column it may mess up with your result set.

Related

T-SQL, get value from xml in a column

I have a table with an XML column (xmlCol) and I am trying to query a value from it.
Here's the xml.
<criteria>
<factor name="Rivers" title="Rivers">
<value dataType="Int32" value="1743" description="Wilson0" />
</factor>
<factor name="OptionalAffProperties" title="Include properties">
<value dataType="String" value="FishingModel" description="Fishing Model" />
</factor>
</criteria>
Here is a select to get the column. select xmlCol from MyTable
I am trying to return the value 1743 to a column called RiverID.
Mike
This should work:
SELECT
xmlCol.value('(//factor[#name="Rivers"]/value/#value)[1]', 'int') As RiverID
FROM
MyTable
value() Method (xml Data Type) - SQL Server | Microsoft Docs
XQuery Language Reference (SQL Server) - SQL Server | Microsoft Docs
To get the attribute value, you can query it like so:
select xmlCol.value('(/criteria/factor/value/#value)[1]', 'int') RiverID
from MyTable
You provide the xml path to the record you are looking for: (/criteria/factor/value
And then the attribute you need: /#value)[1].

inner join not working in dynamics crm query

I am working in a project and I find that they do a query like this:
LinkEntity link = LinkEntity("table1", "account", "table1acountid", "accountid", JoinOperator.Inner)
link.LinkCriteria.AddCondition("accountid", ConditionOperator.Equal, Id);
the relation between table1 and account is 1: N ( we have a lookup to account in table1 form)
The result of the query is always null but when I change Inner with Leftouter, it works.
Is that query correct with inner join? In which case is it supposed to return records of table1?
The condition you add is not necessary, if used to only return accounts associated with table1, that comes implicitly from the LinkEntity statement.
I guess you are missing a new directive on the first line too.
Suggest you use FetchXML Builder for XrmToolBox to componse the query, which can then be converted to QueryExpression code.
I assume this is the query you want (adding a few attributes to return etc)
<fetch >
<entity name='' >
<filter>
<condition attribute='accountid' operator='eq' value='Id' />
</filter>
<link-entity name='table1' from='table1accountid' to='accountid' link-type='inner' />
</entity>
</fetch>

How to iterate dblookup sql result?

How do i iterate SQL result if result is more than one row.
I want read all rows values from a given table(Ex: select * from employee )
Below is the sample code.
<dblookup>
<connection>
<pool>
<password>root123</password>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/ESB_SP_LOANS</url>
<user>root</user>
</pool>
</connection>
<statement>
<sql><![CDATA[select * from TableName]]></sql>
</statement>
</dblookup>
Have a look to https://docs.wso2.com/display/ESB500/DBLookup+Mediator
The DBLookup mediator can set a property from one row in a result set. It cannot return multiple rows

Create CAML query with have a value field with SharePoint column-SharePoint 2010

I have a SharePoint list. It has two columns Start date and End date.
I need to query and get data if (start date + 7 days> End date).
Through CAML builder its not possible to have a SharePoint column on value node and build the query.
Any idea?
I have tried below. But not working.
<Query>
<Where>
<Eq>
<FieldRef Name='EndDate' />
<Value IncludeTimeValue='TRUE' Type='DateTime'><StartDate+7/></Value>
</Eq>
</Where>
</Query>
You can not compare two field of item to each other in CAML query. You can either create computed field and do the compare in it or you can use LINQ. Something like this:
SPList tasks = SPContext.Current.Web.Lists["tasks"];
var ts = from t in tasks.Items.OfType<SPListItem>() where t["DueDate"] == null || (DateTime)t["Modified"] > (DateTime)t["DueDate"] select t;
I would recommend creating a calculated column to calculate the difference between the start and end date:
=DATEDIF([Created], [EndDate],"d")
and then in your camlquery filter by greater or equal than 7 days
<Query>
<Where>
<Geq>
<FieldRef Name="DateDiff"/>
<Value IncludeTimeValue='TRUE' Type='Number'>7<Value>
</Geq>
</Where>
</Query>
Instead of EQ you should use GeQ, LeQ
http://social.msdn.microsoft.com/Forums/sharepoint/en-US/fed59f8e-72e2-46e2-9329-460fd65d7536/caml-query-datetime?forum=sharepointdevelopmentlegacy
https://sharepoint.stackexchange.com/questions/15770/caml-query-with-date-range
i haven't tried it, my self.

Extracting XML data in SQL - too many cross apply statements

I have an xml document containing details from a Statement:
<Statement>
<Id />
<Invoices>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
<Invoice>
<Id />
<Date />
<AmountDue />
etc.
</Invoice>
</Invoices>
</Statement>
This works fine for the Statement specific details:
SET #statementId = #xml.value('(Id)[1]', 'UNIQUEIDENTIFIER');
but it requires a singleton, and only returns the first value. I need ALL of the values for the invoices, not just the first so a singleton won't work.
I am able to get the information out using cross apply statements like this:
SELECT
#statementId AS STATEMENT_ID
Id.value('.', 'uniqueidentifier') AS INVOICE_ID
Date.value('.', 'smalldatetime') AS INVOICE_DATE
Due.value('.', 'decimal') AS INVOICE_AMOUNT_DUE
FROM #xml.nodes('Statement') A(S)
cross apply S.nodes('Invoices/Invoice') B(InvoiceD)
cross apply InvoiceD.nodes('Id') C(Id)
cross apply InvoiceD.nodes('Date') D(Date)
cross apply InvoiceD.nodes('AmountDue') E(Due)
This returns an Id, date, and amount from each Invoice in the Statement - perfect.
My problem comes when I try to extract all of the invoice details. I currently have seven cross apply statements and I got the following message:
"The query processor ran out of internal resources and could not
produce a query plan. This is a rare event and only expected for
extremely complex queries or queries that reference a very large
number of tables or partitions. Please simplify the query. If you
believe you have received this message in error, contact Customer
Support Services for more information."
What I want to do is have one cross apply for the Invoice and narrow down the exact field in the select statement, but unless I use '.' I must make the statement return a singleton and I don't get all of the data that I need.
I have done some research about specifying a namespace within the select statement, but all of the examples set the namespace to be an http address instead of a node in an xml document and I haven't gotten anything to return yet using this approach.
The result I'm looking for is something like this, but with more Invoice Details:
STATEMENT_ID INVOICE_ID INVOICE_DATE INVOICE_AMOUNT_DUE ...
Statement-1-Id Invoice-1-Id Invoice-1-Date Invoice-1-AmountDue ...
Statement-1-Id Invoice-2-Id Invoice-2-Date Invoice-2-AmountDue ...
Statement-1-Id Invoice-3-Id Invoice-3-Date Invoice-3-AmountDue ...
Where should I go from here?
EDIT: I removed some unnecessary information. Getting all of the invoice-specific details is my goal here.
select #XML.value('(Statement/Id/text())[1]', 'uniqueidentifier') as StatementId,
T.N.value('(Id/text())[1]', 'uniqueidentifier') as InvoiceId,
T.N.value('(Date/text())[1]', 'smalldatetime') as InvoiceDate,
T.N.value('(AmountDue/text())[1]', 'decimal') as AmountDue
from #XML.nodes('/Statement/Invoices/Invoice') as T(N)
.nodes will shred your XML to rows so that each row T.N is pointing to an Invoice node of its own. On that node there is only a single Id node so fetching the value specifying a singleton Id[1] works.
You can use Id[1] or (Id/text())[1] but the latter will give you a more efficient execution plan.