Progress OpenEdge like SQL where IN? - progress-4gl

I can do this with a string and it works great.
example:
for each emp no-lock where
lookup(emp.name, "james,john,kerry,david") <> 0:
/* Do something */
end.
Now I have emp.ID that is not a string (it's an integer) how can I do where IN ? I tried similar method as above. but it gives me an error, it says
"incompatible data types"
for each emp no-lock where
lookup(emp.ID, "1,5,89") :
/* Do something */
end.
how do I do this ?
thank yo u

OpenEdge has a SQL-92 engine but you aren't using that. You are using the 4gl engine. There is some limited SQL-89 syntax embedded inside the 4gl engine but it is a bad idea to try to use it. It only leads to pain and suffering
The 4gl has no IN function. To do what you are trying to do with a variable set of integers you would probably want to first create a temp-table and then join the TT with your real table. Something like this:
define temp-table tt_intList
field f1 as integer
.
create tt_intList.
tt_intList.f1 = 1.
create tt_intList.
tt_intList.f1 = 5.
create tt_intList.
tt_intList.f1 = 89.
for each tt_intList, each emp no-lock where emp.Id = tt_intList.f1:
display emp.Id emp.name.
end.

In a large DB table, to make good use of indexes:
FOR EACH emp NO-LOCK WHERE emp.ID = 1 OR emp.ID = 5 OR emp.ID ? 89
A lazy coder in a small table might do:
FOR EACH emp NO-LOCK WHERE LOOKUP (STRING(emp.ID), "1,5,89") > 0

Related

I am having a hard time joining between unrelated domains in JPA

I am experiencing various things while studying JPA, but I am too unfamiliar with it, so I would like to get some advice.
The parts I got stuck in during my study were grouped into three main categories. Could you please take a look at the code below?
#Repository
public interface TestRepository extends JpaRepository<TestEntity,Long> {
#Query(" SELECT
, A.test1
, A.test2
, B.test1
, B.test2
FROM TEST_TABLE1 A
LEFT JOIN TEST_TABLE2 B
ON A.test_no = B.test_no
WHERE A.test3 = ?1 # Here's the first question
if(VO.test4 is not null) AND B.test4 = ?2") # Here's the second question
List<Object[] # Here's the third question> getTestList(VO);
}
First, is it possible to extract test3 from the VO received when using native sql?
Usually, String test1 is used like this, but I wonder if there is any other way other than this.
Second, if extracting is possible in VO, can you add a query in #QUERY depending on whether Test4 is valued or not?
Thirdly, if I use List<Object[]>, can the result of executing a query that is not in the already created entity (eg, test1 in TEST_TABLE2, which is not in the entity of TEST_TABLE1) can be included?,
First, is it possible to extract test3 from the VO received when using native sql? Usually, String test1 is used like this, but I wonder if there is any other way other than this.
Yes, it is possible.
You must use, eg where :#{[0].test3} is equals vo.test3
[0] is position the first param, past for method annotated with #Query
#Query(value = "SELECT a.test1, a.test2, b.test1, b.test2
FROM test_table1 a
LEFT JOIN test_table2 b ON a.test_no = b.test_no
WHERE a.test3 = :#{[0].test3}", nativeQuery = true)
List<Object[]> getList(VO);
Second, if extracting is possible in VO, can you add a query in #QUERY depending on whether Test4 is valued or not?
You can use a trick eg:
SELECT ... FROM table a
LEFT JOIN table b ON a.id = b.id
WHERE a.test3 = :#{[0].test3}
AND (:#{[0].test4} IS NOT NULL AND b.test4 = :#{[0].test4})
Thirdly, if I use List<Object[]>, can the result of executing a query that is not in the already created entity (eg, test1 in TEST_TABLE2, which is not in the entity of TEST_TABLE1) can be included?
Sorry, but I not understand the third question.
Maybe this tutorial will help you: https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions

Add a single field to model using raw SQL

I'm developing an extension for TYPO3 CMS 8.7.8. I'm using query->statement() to select all fields from a single table, plus 1 field from another table. I get a QueryResult with the proper models and I would like to have that 1 extra field added to them. Is that possible?
You can do SQL queries with the ->statement(...) method and in that, use normal JOIN commands
From the documentation
$result = $query->statement('SELECT * FROM tx_sjroffers_domain_model_offer
WHERE title LIKE ? AND organization IN ?', array('%climbing%', array(33,47)));
So you can do JOINs on whatever table you want to (also code from the documentation)
LEFT JOIN tx_blogexample_person
ON tx_blogexample_post.author = tx_blogexample_person.uid
But you will end up with the raw data from the mysql query. If you want to transform it into a object, use the Property Mapper
You can use JOIN in your sql statments like below.
$query = $this->createQuery();
$sql = 'SELECT single.*,another.field_anme AS fields_name
FROM
tx_single_table_name single
JOIN
tx_another_table_name another
ON
single.fields = another.uid
WHERE
O.deleted = 0
AND O.hidden=0
AND O.uid=' . $orderId;
return $query->statement($sql)->execute();

Cannot access temp table in dynamic TSQL

I am creating a temporary table in some dynamic SQL. But when I call it it throws an "Invalid object name '#Settlement_Data_Grouped'" error.
I am assuming it's because dynamic SQL uses it's own seperate instance? So that it is dropped and not available to the outside SQL? It works when I use ##Settlement_Data_Grouped or create a table. But this doesn't help when multiple people are calling the sproc.
I'm thinking I could check if the table exists but that would mean I would have to delete contents and different users may require different outputs which would mean it would not work.
So does anyone have a solution/suggestion I can use where multiple people can be calling the same sproc?
IMHO you do not need the Dynamic SQL. You can change your code like something below and that will give you same result as you are trying to accomplish. Please check for any syntax error if any. I would have provided you full query but in your question you have screenshot instead of the code. So here it goes.
If you want to use Temp Tables:
SELECT
......
INTO #Settlement_Data_Grouped
FROM #Settlement_Data
WHERE (Payment_Date < Settlement_Date AND #outputType = 1) ---This will be true when you have #outputType = 1
OR #outputType = 0 ---This will be true when you have #outputType = 0
GROUP BY Part_No
,NAME
,Order_No
,Invoice_No
-------------
SELECT
......
FROM #Settlement_Data_Grouped
If you want to use CTE:
WITH Settlement_Data_Grouped
AS (
SELECT
......
FROM #Settlement_Data
WHERE (Payment_Date < Settlement_Date AND #outputType = 1) ---This will be true when you have #outputType = 1
OR #outputType = 0 ---This will be ture when you have #outputType = 0
GROUP BY Part_No
,NAME
,Order_No
,Invoice_No
)
SELECT
......
FROM Settlement_Data_Grouped
The problem is that the temp table only exists within the scope of the dynamic SQL execution context. The way around it would be to create the temp table outside of the dynamic SQL and then insert into it:
CREATE TABLE #Settlement_Data_Grouped (PartNo varchar(50) ......)
INSERT INTO #Settlement_Data_Grouped
EXEC(#selectSQL)

Compare 2 fields in where statement ORMLite

Is it possible to compare 2 fields from the table in where condition in ORMLite without using where().raw(statement, args)?
SQL query looks like
select
*
from
table
where
table.f1 = table.f2
try This ... i hope Its Work For You !!!
select (case when (table.f1 = table.f2 ) then 'EQUAL' else 'NOT_EQUAL' end) as one from table
OR
SELECT * FROM table WHERE f1 LIKE 'f2';
OR
SELECT * FROM table WHERE f1 = f2;
Don't know why I missed this last time. ORM Lite doc contains the answer:
ColumnArg object is designed to compare one column against another.
QueryBuilder<Table, String> queryBuilder = tableDao.queryBuilder();
queryBuilder.where().eq(Table.f1,
new ColumnArg(Table.f2));
List<Table> results = queryBuilder.query();

how to List the top ten customers form the given start date with greater cost/price of orders using progress 4gl

a single customer could have multiple orders and corresponding cost.
now the cost/price has to be added and according to the max price the customer's should be displayed.
i have just written the skeleton of the prog , please help me.
define temp-table ttorder
field ocust-num like order.cust-num
field oorder-num like order.order-num.
define variable i as int.
define variable a as int.
define temp-table ttorderln
field oprice like order-line.price.
for each order where order-date > 01/08/93 /*by cust-num*/ .
create ttorder .
assign
ttorder.ocust-num =cust-num
ttorder.oorder-num = order-num.
for each order-line where order-line.order-num = ttorder.oorder-num break by ocust-num.
i = order-line.price.
a = i + a.
/* display cust-num order-num a. */
if last-of (ttorder.ocust-num) then
do:
create ttorderln.
ttorderln.oprice=a.
end.
display ttorderln.
end.
end.
If you're looking for the top customers, you should use a temp table based on customers, not orders. Go through the orders and order lines, accumulating the amounts by customer.
define temp-table ttcust
field cust-num like order.cust-num
field order-tot as decimal
index idx1 cust-num
index idx2 order-tot.
define variable i as integer.
for each order where order-date > 01/08/93:
/* Find or create a customer temp record. */
find first ttcust where ttcust.cust-num = order.cust-num no-error.
if not available(ttcust) then
do:
create ttcust.
ttcust.cust-num = order.cust-num.
end.
/* Add up the order lines. */
for each order-line where order-line.order-num = order.order-num no-lock:
ttcust.order-tot = ttcust.order-tot + order-line.extended-price.
end.
end.
/* Display the top 10. */
for each ttcust by order-tot descending:
i = i + 1.
message "Cust: " ttcust.cust-num skip
"Total: " ttcust.order-tot view-as alert-box.
if i >= 10 then leave.
end.