Dynamic Sort BY in a Query Prepare with a Join - openedge

I want to join pt_mstr and in_mstr to create my report screen for which I have written this code i want to sort my output screen based on either prod line or status so i have defined a variable lvc_sort sort by prod line if i give 1 and similarly 2 for status
IF lvc_sort = 1 THEN DO:
FOR EACH pt_mstr no-lock
WHERE pt_domain = global_domain
AND pt_part >= lvc_part
AND pt_part <= lvc_part1
AND pt_part_type >= lvc_part_type
AND pt_part_type <= lvc_part_type1
AND pt_prod_line >= lvc_prod_line
AND pt_prod_line <= lvc_prod_line1
AND pt_status >= lvc_status
AND pt_status <= lvc_status1,
EACH in_mstr
WHERE in_domain = pt_domain
AND in_part = pt_part
BREAK BY pt_prod_line:
FIND FIRST tt NO-LOCK
WHERE tt_part = pt_part
AND tt_site = in_site NO-ERROR.
Is this the correct approach or can it be done in some other way?

You can use a query then you have a section with a different by clause
DEFINE VARIABLE cQuery AS CHARACTER NO-UNDO.
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
cQuery = "FOR EACH pt_mstr no-lock " +
" WHERE pt_domain = " + QUOTER(global_domain) +
" AND pt_part >= " + QUOTER(lvc_part) +
" AND pt_part <= " + QUOTER(lvc_part1) +
" AND pt_part_type >= " + QUOTER(lvc_part_type) +
" AND pt_part_type <= " + QUOTER(lvc_part_type1) +
" AND pt_prod_line >= " + QUOTER(lvc_prod_line) +
" AND pt_prod_line <= " + QUOTER(lvc_prod_line1) +
" AND pt_status >= " + QUOTER(lvc_status) +
" AND pt_status <= " + QUOTER(lvc_status1) +
", EACH in_mstr " +
" WHERE in_domain = " + QUOTER(pt_domain) +
" AND in_part = " + QUOTER(pt_part).
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(BUFFER pt_mstr:HANDLE, BUFFER in_mstr:HANDLE).
IF lvc_sort = 1 THEN
cQuery = cQuery + " BREAK BY pt_prod_line ".
ELSE
cQuery = cQuery + " BREAK BY pt_status ".
hQuery:QUERY-PREPARE(cQuery).
hQuery:QUERY-OPEN.
// alle durch
DO WHILE hQuery:GET-NEXT() :
FIND FIRST tt NO-LOCK
WHERE tt_part = pt_part
AND tt_site = in_site NO-ERROR.
END.
FINALLY:
hQuery:QUERY-CLOSE () NO-ERROR.
DELETE OBJECT hQuery NO-ERROR.
END FINALLY.

Related

QUERY-PREPARE() taking too long to load. Is it the best option?

Every it-codigo has 1 or more es-codigo. I'm trying to find all the es-codigo of the it-codigo input, but it's taking too long. Did I do anything wrong in my code? For what I have seen, it's all right, unless there's something I don't know about that I'm doing wrong. Is QUERY-PREPARE() the best option in this case?
DEF VAR qEstrutura AS CHAR.
IF pi-cod-emitente <> 0 THEN DO:
qEstrutura = " WHERE item-cli.cod-emitente = " + QUOTER(pi-cod-emitente).
END.
IF pc-it-codigo <> "" THEN DO:
IF qEstrutura = "" THEN
qEstrutura = " WHERE estrutura.it-codigo = " + QUOTER(pc-it-codigo).
ELSE
qEstrutura = qEstrutura + " AND estrutura.it-codigo = " + QUOTER(pc-it-codigo).
END.
IF pc-item-cli <> "" THEN DO:
IF qEstrutura = "" THEN
qEstrutura = " WHERE item-cli.item-do-cli = " + QUOTER(pc-item-cli).
ELSE
qEstrutura = qEstrutura + " AND item-cli.item-do-cli = " + QUOTER(pc-item-cli).
END.
cQuery = cQuery + " FOR EACH item-cli, ".
cQuery = cQuery + " EACH estrutura ".
cQuery = cQuery + qEstrutura + " BREAK BY estrutura.es-codigo".
QUERY qConsulta:QUERY-PREPARE(cQuery).
QUERY qConsulta:QUERY-OPEN().
GET FIRST qConsulta.
DO WHILE AVAILABLE item-cli:
IF QUERY qConsulta:FIRST-OF(1) THEN DO:
CREATE tt-estrutura.
ASSIGN
tt-estrutura.it-codigo = estrutura.it-codigo
tt-estrutura.es-codigo = estrutura.es-codigo
.
GET NEXT qConsulta.
END.
END.
QUERY qConsulta:QUERY-CLOSE().
FOR EACH tt-estrutura:
DISP tt-estrutura.
END.
I believe it's the QUERY-OPEN() that takes time. Not QUERY-PREPARE().
Your query is only performing selection (WHERE) and sort (BY) on the second table. That makes is difficult to utilize indizes. The OpenEdge ABL query engine does not support flipping the buffer-sequence. Try turning the query around:
FOR EACH estrutura WHERE ......, FIRST item-cli.

SQLite not Deleting records with multiple conditions

Sorry..! It was a logical mistake.! I solved it.!
It is not deleting anything, but there are records, what's wrong?
SQLite Code:
dbWritable.delete(TABLE_NAME, COL_Student_ID + " == " + Student_ID + " AND " + COL_ID + " NOT IN " + pramIDs, null);
Query:
DELETE FROM student_attendances
WHERE Student_ID == 1036 AND ID NOT IN
(733703,733745,733787,733829,733871,733913,733955,733997,734039,734081,734123,734165,734207,734249,734291,734333,734375,734417,734459,734501,734543,734585,734627,734669,734711,734753,734795,734837,734879,734921,734963,735005,735047,735089,735131,735173,735215,735257,735299,735341,735383,735425,735467,735509,735551,735593,735635,735677,735719,735761,735803,735845,735887,735929,735971,736013,736055,736097,736139,736181,736223,736265,736307,736349,736391,736433,736475,736517,736559,736601 )

using placeholder in sql query in asp.net

I am an ASP.Net developer & using sql server CE 4.0 I want to know how to use place holder for this code, As this query is currently vulnerable to sql injection. Place holder can prevent this but the problem is for example query = "SELECT * FROM TABLE WHERE TITLE = #0" but in my query the value of #0 is dynamically added to query how do i use place holder
this is the code
if (Request["search"] != "" && Request["search"] != null)
{
var search = Request["search"].Trim();
string[] querynew = search.Split(' ');
var searchquery = "and ";
foreach (string word in querynew)
{
searchquery += "response_table.adtitle LIKE '%" + word + "%' OR ";
}
sql += searchquery.Remove(searchquery.Length - 4);
}
if (Request["min"] != "" && Request["min"] != null && Request["max"] != null && Request["max"] != "")
{
sql = sql + " and (CAST(response_table.price AS Float)) between " + Request["min"].Trim() + " AND " + Request["max"].Trim();
}
// 3. the order clause
switch (Request["sort"])
{
case "recent":
sql = sql + "ORDER BY response_table.response_ID DESC OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
case "hightolow":
sql = sql + "ORDER BY CAST(response_table.price AS Float) Desc OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
case "lowtohigh":
sql = sql + "ORDER BY CAST(response_table.price AS Float) ASC OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
default:
break;
}
result = db.Query(sql);
Thank You
Using parameters (instead of concatenating strings) allows you to optimize performance of your queries.
You can use a SqlCeCommand. It has a collection of parameters and you can find a sample here regarding how to use them.

Variable 'per' not in scope error in XQuery

I am getting 'Variable 'per' not in scope error' error, when I tried to execute below code in Java.
String xq = "declare variable $per1 as document-node(element(*, xs:untyped)) := " +
"fn:parse-xml($per);" +
"declare variable $job1 as document-node(element(*, xs:untyped)) := fn:parse-xml($job);" +
"for $i in $per1//pimergednodes/Get__CompIntfc__CI_PERSONAL_DATAResponse,\n" +
" $j in $job1//jobmergednodes/Get__CompIntfc__CI_JOB_DATAResponse[PROP_EMPLID = $i/PROP_EMPLID]\n" +
"\n" +
" return\n" +
" <emp>\n" +
" {\n" +
" $i/PROP_EMPLID,\n" +
" $i/PROP_BIRTHDATE,\n" +
" <coll_names>\n" +
" {\n" +
" $i/COLL_NAME_TYPE_VW/COLL_NAMES\n" +
" }\n" +
" </coll_names>,\n" +
"\n" +
" $i/PROP_BIRTHDATE/COLL_NAME_TYPE_VW/PROP_FIRST_NAME,\n" +
" $j/COLL_JOB/PROP_DEPTID\n" +
"\n" +
" }\n" +
" </emp>";
XQDataSource xds = new oracle.xquery.xqj.OXQDataSource();
XQConnection conn = xds.getConnection();
XQPreparedExpression pEx = conn.prepareExpression(xq); ==> error raised in this call.
Can somebody help me in fixing this error.
Thanks In Advance,
Maviswa
You reference $per in fn:parse-xml($per), but your code doesn't define that variable anywhere. I see $per1, but no $per. I suspect you'll run into the same problem with $job.
For debugging, print out the xq string so you can see the XQuery by itself without all the Java string escaping, which just adds a lot of noise.

Why does this query give me an exception?

string updateIncomeData = #"INSERT INTO TEAM_FUNDS_DETAILS("
+ "COMPONENT_TYPE,COMPONENT_NAME,COMPONENT_AMOUNT, YEAR_FOR, MONTH_FOR)"
+ "VALUES(" + Convert.ToInt32(TeamFundDetailsEnumClass.ComponentType.Income)
+ " , ?, ?,"
+ ddlYear.SelectedIndex + ", " + ddlMonth.SelectedIndex + ")"
This parametrized query gives me an exception that tells me that there is an error near "?". What is the error. Please correct it.
I am purely guessing but should it be year.selecteditem? not selectedindex?
I don't understand why you would want to mix up the parameter substitution.
Specify all five columns as parameters and set the values that way.
"INSERT INTO TEAM_FUNDS_DETAILS " +
"(COMPONENT_TYPE,COMPONENT_NAME,COMPONENT_AMOUNT, YEAR_FOR, MONTH_FOR) " +
"VALUES(? , ?, ?,?, ?)"
You must set the parameterized values (the ones with the question mark). Here is a similar example in VB.NET:
' Make a Command for this connection
' and this transaction.
Dim cmd As New OleDb.OleDbCommand( _
"SELECT * FROM People WHERE FirstName=? AND " & _
"LastName=?", _
connUsers)
' Create parameters for the query.
cmd.Parameters.Add(New _
OleDb.OleDbParameter("FirstName", first_name))
cmd.Parameters.Add(New OleDb.OleDbParameter("LastName", _
last_name))
If you don't want to use parameterized queries, just substitute the question mark with the default value, or the variable with the value:
string updateIncomeData = #"INSERT INTO TEAM_FUNDS_DETAILS("
+ "COMPONENT_TYPE,COMPONENT_NAME,COMPONENT_AMOUNT, YEAR_FOR, MONTH_FOR)"
+ "VALUES(" + Convert.ToInt32(TeamFundDetailsEnumClass.ComponentType.Income)
+ " , '', 0,"
+ ddlYear.SelectedIndex + ", " + ddlMonth.SelectedIndex + ")"
or
string updateIncomeData = #"INSERT INTO TEAM_FUNDS_DETAILS("
+ "COMPONENT_TYPE,COMPONENT_NAME,COMPONENT_AMOUNT, YEAR_FOR, MONTH_FOR)"
+ "VALUES(" + Convert.ToInt32(TeamFundDetailsEnumClass.ComponentType.Income)
+ " , '" + myComponentName + "', " + myComponentAmount,"
+ ddlYear.SelectedIndex + ", " + ddlMonth.SelectedIndex + ")"
ddlMonth.SelectedItem.Value

Resources