- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
oracle view rownum problem
Joined: 08-Sep-2004
Has anyone come across this problem?
I have an entity based on a view. I use fetchentitycollection paging feature and found a problem when I was filtering that the row count which I get using getdbcount said 863, but rows returned were only 10 on first page when pagesize is 100. So I looked at the query llblgen sends over and it was:
SELECT *
FROM (SELECT a.*, ROWNUM r___
FROM (SELECT "PCPACP"."SOMEVIEW"."COL1",
"PCPACP"."SOMEVIEW"."COL2",
"PCPACP"."SOMEVIEW"."COL3",
"PCPACP"."SOMEVIEW"."COL4",
"PCPACP"."SOMEVIEW"."COL5",
"PCPACP"."SOMEVIEW"."COL6",
"PCPACP"."SOMEVIEW"."COL7",
"PCPACP"."SOMEVIEW"."COL8",
"PCPACP"."SOMEVIEW"."COL9",
"PCPACP"."SOMEVIEW"."COL10",
"PCPACP"."SOMEVIEW"."COL11",
"PCPACP"."SOMEVIEW"."COL12",
"PCPACP"."SOMEVIEW"."COL13"
FROM "PCPACP"."SOMEVIEW"
WHERE ((( "PCPACP"."SOMEVIEW"."COL13" = :col131
OR "PCPACP"."SOMEVIEW"."COL13" = :col132
)
)
)
ORDER BY "PCPACP"."SOMEVIEW"."COL3" ASC) a
WHERE ROWNUM < :rownostart__)
WHERE r___ >= :rownoend__
Now what I did was take this query and run it without any filtering on rownums and I got back 863 rows. I modified the query thus
SELECT a.*, ROWNUM r___
FROM (SELECT "PCPACP"."SOMEVIEW"."COL1",
"PCPACP"."SOMEVIEW"."COL2",
"PCPACP"."SOMEVIEW"."COL3",
"PCPACP"."SOMEVIEW"."COL4",
"PCPACP"."SOMEVIEW"."COL5",
"PCPACP"."SOMEVIEW"."COL6",
"PCPACP"."SOMEVIEW"."COL7",
"PCPACP"."SOMEVIEW"."COL8",
"PCPACP"."SOMEVIEW"."COL9",
"PCPACP"."SOMEVIEW"."COL10",
"PCPACP"."SOMEVIEW"."COL11",
"PCPACP"."SOMEVIEW"."COL12",
"PCPACP"."SOMEVIEW"."COL13"
FROM "PCPACP"."SOMEVIEW"
WHERE ((( "PCPACP"."SOMEVIEW"."COL13" = :col131
OR "PCPACP"."SOMEVIEW"."COL13" = :col132
)
)
)
ORDER BY "PCPACP"."SOMEVIEW"."COL3" ASC) a
WHERE ROWNUM < 800
I get only 15 rows running the above query. Did anyone face this problem before. I am at my wits end now. Maybe rownum and views do not make a good combination?
Joined: 08-Sep-2004
bclubb, the original code is pretty much mundane like the countless times I have written them.
manager code*******
public static int GetPPCount(IPredicateExpression filter, DataAccessAdapter adapterToUse)
{
int toReturn = 0;
IRelationPredicateBucket bucket = new RelationPredicateBucket();
bucket.PredicateExpression.Add(filter);
object result = adapterToUse.GetDbCount(new PPEntityFactory().CreateFields(), bucket);
if( result != null )
{
toReturn = (int)result;
}
return toReturn;
}
public static EntityCollection FetchPPCollection(IPredicateExpression filter, ISortExpression sorter, int page, int pageSize, DataAccessAdapter adapterToUse)
{
EntityCollection toReturn = new EntityCollection(new PPEntityFactory());
IRelationPredicateBucket bucket = new RelationPredicateBucket();
bucket.PredicateExpression.Add(filter);
adapterToUse.FetchEntityCollection(toReturn, bucket, 0, sorter, page, pageSize);
return toReturn;
}
*************data grid bind code ******************
private void BindGrid()
{
EntityCollection list;
listPageSize.Visible = false;
lbl1.Visible = false;
lbl2.Visible = false;
dlSortOrder.Visible = false;
dlSortField.Visible = false;
btnUpdate.Visible = false;
DG.Visible = false;
DG.PageSize = Convert.ToInt32(listPageSize.SelectedValue);
try
{
IPredicateExpression A = (IPredicateExpression)this.SearchCriteria;
ISortExpression sorter = this.GetSortExpression();
using (DataAccessAdapter adapter = DataAccessAdapterFactory.CreateAdapter(Request["net"],true))
{
adapter.CommandTimeOut = 600;
list = ReportManager.FetchPPCollection(
A,
sorter,
DG.CurrentPageIndex+1,
Convert.ToInt32(listPageSize.SelectedValue),
adapter);
adapter.CloseConnection();
}
}
catch(ORMQueryExecutionException E)
{
lblError.Text = E.Message+"<br>**<br>"+E.QueryExecuted+"<br>**<br>"+E.Source+"<br>**<br>"+E.StackTrace;
return;
}
catch(Exception E)
{
lblError.Text = E.Message+"<br>**<br>"+E.InnerException+"<br>**<br>"+E.Source+"<br>**<br>"+E.StackTrace;
return;
}
if (list.Count > 0)
{
DG.VirtualItemCount = (int)this.TotalCountOfRows;
listPageSize.Visible = true;
lbl1.Visible = true;
lbl2.Visible = true;
dlSortOrder.Visible = true;
dlSortField.Visible = true;
btnUpdate.Visible = true;
DG.Visible = true;
DG.DataSource = list;
DG.DataBind();
}
}
code to create filter*
public IPredicateExpression GetPredicateExpression()
{
IPredicateExpression A = new PredicateExpression();
if (txtID.Text.Trim() != String.Empty)
{
string[] keywords = txtID.Text.Split();
for (int i = 0; i < keywords.Length; i++)
{
if(i==0)
{
A.Add(PredicateFactory.CompareValue(PPFieldIndex.PAT_ID, ComparisonOperator.Equal,keywords[i]));
}
else
{
A.AddWithOr(PredicateFactory.CompareValue(PPFieldIndex.PAT_ID, ComparisonOperator.Equal,keywords[i]));
}
}
}
IPredicateExpression B = new PredicateExpression();
if (txtName.Text.Trim() != String.Empty)
{
string[] keywords = txtName.Text.Split();
for (int i = 0; i < keywords.Length; i++)
{
if(i==0)
{
FieldLikePredicate likeFilter=PredicateFactory.Like(PPFieldIndex.NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter.CaseSensitiveCollation = true;
B.Add(likeFilter);
}
else
{
FieldLikePredicate likeFilter=PredicateFactory.Like(PPFieldIndex.NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter.CaseSensitiveCollation = true;
B.AddWithOr(likeFilter);
}
}
}
IPredicateExpression C = new PredicateExpression();
if (txtProviderID.Text.Trim() != String.Empty)
{
C.Add(PredicateFactory.CompareValue(PPFieldIndex.PCP_ID, ComparisonOperator.Equal, txtProviderID.Text.Trim()));
C.AddWithOr(PredicateFactory.CompareValue(PPFieldIndex.ACP_ID, ComparisonOperator.Equal, txtProviderID.Text.Trim()));
C.AddWithOr(PredicateFactory.CompareValue(PPFieldIndex.AP_ID, ComparisonOperator.Equal, txtProviderID.Text.Trim()));
C.AddWithOr(PredicateFactory.CompareValue(PPFieldIndex.BP_ID, ComparisonOperator.Equal, txtProviderID.Text.Trim()));
}
IPredicateExpression D = new PredicateExpression();
if (txtProviderName.Text.Trim() != String.Empty)
{
string[] keywords = txtProviderName.Text.Split();
for (int i = 0; i < keywords.Length; i++)
{
if(i==0)
{
FieldLikePredicate likeFilter1=PredicateFactory.Like(PPFieldIndex.PCP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter1.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter2=PredicateFactory.Like(PPFieldIndex.ACP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter2.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter3=PredicateFactory.Like(PPFieldIndex.AP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter3.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter4=PredicateFactory.Like(PPFieldIndex.BP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter4.CaseSensitiveCollation = true;
D.Add(likeFilter1);
D.AddWithOr(likeFilter2);
D.AddWithOr(likeFilter3);
D.AddWithOr(likeFilter4);
}
else
{
FieldLikePredicate likeFilter1=PredicateFactory.Like(PPFieldIndex.PCP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter1.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter2=PredicateFactory.Like(PPFieldIndex.ACP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter2.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter3=PredicateFactory.Like(PPFieldIndex.AP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter3.CaseSensitiveCollation = true;
FieldLikePredicate likeFilter4=PredicateFactory.Like(PPFieldIndex.BP_NAME,"%" + keywords[i].ToUpper() + "%");
likeFilter4.CaseSensitiveCollation = true;
D.AddWithOr(likeFilter1);
D.AddWithOr(likeFilter2);
D.AddWithOr(likeFilter3);
D.AddWithOr(likeFilter4);
}
}
}
IPredicateExpression E = new PredicateExpression();
if (dlLocation.SelectedValue != "-1")
{
E.Add(PredicateFactory.CompareValue(PPFieldIndex.LOCATION_ID, ComparisonOperator.Equal,Int32.Parse(dlLocation.SelectedValue)));
}
IPredicateExpression F = new PredicateExpression();
if (txtDeptCode.Text.Trim() != String.Empty)
{
string[] keywords = txtDeptCode.Text.Split();
for (int i = 0; i < keywords.Length; i++)
{
if(i==0)
{
F.Add(PredicateFactory.CompareValue(PPFieldIndex.DEPT_CODE, ComparisonOperator.Equal,keywords[i]));
}
else
{
F.AddWithOr(PredicateFactory.CompareValue(PPFieldIndex.DEPT_CODE, ComparisonOperator.Equal,keywords[i]));
}
}
}
IPredicateExpression toReturn = new PredicateExpression();
toReturn.AddWithAnd(A)
.AddWithAnd(B)
.AddWithAnd(C)
.AddWithAnd(D)
.AddWithAnd(E)
.AddWithAnd(F);
return toReturn;
}
It will great if you can give this a look over.
Do you have an order by clause in your view? If so, could you try (for testing) to remove it and try again? Also, try without the sortexpression and try again. Though it is strange...
Joined: 08-Sep-2004
I dont have any orderby in the view.
I did more testing and the results are: 1. Removing sortexpression got everything working properly again. Results are clearly unordered.
-
Through the application, when using sorting, if on a particular field I have 2 conditions, I observe strange behavior; i.e only 10 records returned although rowcount is 1500 etc.
-
Through the application, when using sorting, if on a particular field I have only 1 condition, things work fine. So I was ready to restrict the application to use only one condition on that particular field. But, just to make sure that I dont have any future problems, I ran the following in toad, which seems to be the queries that llblgen sends to oracle:
SELECT COUNT (*) AS numberofrows
FROM (SELECT "PCPACP"."PP"."PP_ID",
"PCPACP"."PP"."PP_NAME",
"PCPACP"."PP"."PP_ID2",
"PCPACP"."PP"."PP_DOB",
"PCPACP"."PP"."PCP_ID",
"PCPACP"."PP"."PCP_NAME",
"PCPACP"."PP"."PCP_TITLE",
"PCPACP"."PP"."PCP_UPD_DT",
"PCPACP"."PP"."ACP_ID",
"PCPACP"."PP"."ACP_NAME",
"PCPACP"."PP"."ACP_TITLE",
"PCPACP"."PP"."ACP_UPD_DT",
"PCPACP"."PP"."BP_ID",
"PCPACP"."PP"."BP_NAME",
"PCPACP"."PP"."BP_TITLE",
"PCPACP"."PP"."BP_DATE_TIME",
"PCPACP"."PP"."BP_VISIT_ID",
"PCPACP"."PP"."AP_ID",
"PCPACP"."PP"."AP_NAME",
"PCPACP"."PP"."AP_TITLE",
"PCPACP"."PP"."AP_VISIT_ID",
"PCPACP"."PP"."AP_DATE_TIME",
"PCPACP"."PP"."LOCATION_ID",
"PCPACP"."PP"."DEPT_CODE",
"PCPACP"."PP"."LOCATION_NAME"
FROM "PCPACP"."PP"
WHERE ((("PCPACP"."PP"."DEPT_CODE" = '000')
)
)) tmpresult
I got 8791 as the answer. Then I ran the foll. in toad:
SELECT *
FROM (SELECT a.*, ROWNUM r___
FROM (SELECT "PCPACP"."PP"."PP_ID",
"PCPACP"."PP"."PP_NAME",
"PCPACP"."PP"."PP_ID2",
"PCPACP"."PP"."PP_DOB",
"PCPACP"."PP"."PCP_ID",
"PCPACP"."PP"."PCP_NAME",
"PCPACP"."PP"."PCP_TITLE",
"PCPACP"."PP"."PCP_UPD_DT",
"PCPACP"."PP"."ACP_ID",
"PCPACP"."PP"."ACP_NAME",
"PCPACP"."PP"."ACP_TITLE",
"PCPACP"."PP"."ACP_UPD_DT",
"PCPACP"."PP"."BP_ID",
"PCPACP"."PP"."BP_NAME",
"PCPACP"."PP"."BP_TITLE",
"PCPACP"."PP"."BP_DATE_TIME",
"PCPACP"."PP"."BP_VISIT_ID",
"PCPACP"."PP"."AP_ID",
"PCPACP"."PP"."AP_NAME",
"PCPACP"."PP"."AP_TITLE",
"PCPACP"."PP"."AP_VISIT_ID",
"PCPACP"."PP"."AP_DATE_TIME",
"PCPACP"."PP"."LOCATION_ID",
"PCPACP"."PP"."DEPT_CODE",
"PCPACP"."PP"."LOCATION_NAME"
FROM "PCPACP"."PP"
WHERE ("PCPACP"."PP"."DEPT_CODE" = '000')
ORDER BY "PCPACP"."PP"."BP_ID" ASC
) a
WHERE ROWNUM < 1000
)
WHERE r___ >= 350
I got back nothing.
Strange isn't it? Am I doing something wrong? Why would application using llblgen + sorting work and not the same queries in toad?
My feeling is that sorting is the culprit somehow. Any thoughts? How do you think I should approach this now?
I've formatted the second query a little.
The weird thing is: the order by is in the query from which rows are selected. So ROWNUM should be based on that order.
if you instead do:
SELECT a.*, ROWNUM r___
FROM (SELECT "PCPACP"."PP"."PP_ID",
"PCPACP"."PP"."PP_NAME",
"PCPACP"."PP"."PP_ID2",
"PCPACP"."PP"."PP_DOB",
"PCPACP"."PP"."PCP_ID",
"PCPACP"."PP"."PCP_NAME",
"PCPACP"."PP"."PCP_TITLE",
"PCPACP"."PP"."PCP_UPD_DT",
"PCPACP"."PP"."ACP_ID",
"PCPACP"."PP"."ACP_NAME",
"PCPACP"."PP"."ACP_TITLE",
"PCPACP"."PP"."ACP_UPD_DT",
"PCPACP"."PP"."BP_ID",
"PCPACP"."PP"."BP_NAME",
"PCPACP"."PP"."BP_TITLE",
"PCPACP"."PP"."BP_DATE_TIME",
"PCPACP"."PP"."BP_VISIT_ID",
"PCPACP"."PP"."AP_ID",
"PCPACP"."PP"."AP_NAME",
"PCPACP"."PP"."AP_TITLE",
"PCPACP"."PP"."AP_VISIT_ID",
"PCPACP"."PP"."AP_DATE_TIME",
"PCPACP"."PP"."LOCATION_ID",
"PCPACP"."PP"."DEPT_CODE",
"PCPACP"."PP"."LOCATION_NAME"
FROM "PCPACP"."PP"
WHERE ("PCPACP"."PP"."DEPT_CODE" = '000')
ORDER BY "PCPACP"."PP"."BP_ID" ASC
) a
What's the result?
Joined: 08-Sep-2004
Otis wrote:
I've formatted the second query a little.
The weird thing is: the order by is in the query from which rows are selected. So ROWNUM should be based on that order.
if you instead do:
SELECT a.*, ROWNUM r___ FROM (SELECT "PCPACP"."PP"."PP_ID", "PCPACP"."PP"."PP_NAME", "PCPACP"."PP"."PP_ID2", "PCPACP"."PP"."PP_DOB", "PCPACP"."PP"."PCP_ID", "PCPACP"."PP"."PCP_NAME", "PCPACP"."PP"."PCP_TITLE", "PCPACP"."PP"."PCP_UPD_DT", "PCPACP"."PP"."ACP_ID", "PCPACP"."PP"."ACP_NAME", "PCPACP"."PP"."ACP_TITLE", "PCPACP"."PP"."ACP_UPD_DT", "PCPACP"."PP"."BP_ID", "PCPACP"."PP"."BP_NAME", "PCPACP"."PP"."BP_TITLE", "PCPACP"."PP"."BP_DATE_TIME", "PCPACP"."PP"."BP_VISIT_ID", "PCPACP"."PP"."AP_ID", "PCPACP"."PP"."AP_NAME", "PCPACP"."PP"."AP_TITLE", "PCPACP"."PP"."AP_VISIT_ID", "PCPACP"."PP"."AP_DATE_TIME", "PCPACP"."PP"."LOCATION_ID", "PCPACP"."PP"."DEPT_CODE", "PCPACP"."PP"."LOCATION_NAME" FROM "PCPACP"."PP" WHERE ("PCPACP"."PP"."DEPT_CODE" = '000') ORDER BY "PCPACP"."PP"."BP_ID" ASC ) a
What's the result?
Works as it should, displaying rownum from 1 to count(*). This problem might be be an undocumented oracle feature