Itgeneor335 Statement caused an error. A required filter is missing

Ik heb net de BETA versie van de Invantive Query Tool geïnstalleerd (20.1.497) en krijg met onderstaande query de foutmelding

itgeneor335: A required filter is missing.

Zit er een fout in mijn query die ik moet aanpassen na de laatste wijzigingen in Exact?

create or replace table sor@inmemorystorage
as
select sor.* prefix with 'sor_'
,      ads.* prefix with 'ads_'
,      con.* prefix with  'con_'
from   exactonlinerest..SalesOrders@eol sor
join   exactonlinerest..addresses@eol ads
on     ads.id = sor.deliveryaddress
join   exactonlinerest..Contacts@eol con
on     con.account = sor.Invoiceto
where  sor.DeliveryDate between trunc(sysdate)-40 and trunc(sysdate)
and    sor.DeliveryStatus = 12
and    sor.warehousecode = 1
--and    sor.Ordernumber < 92907
order 
by     sor.ordernumber 

insert into phtestorders@sql
( Orderid
, OrderNumber
, OrderDate
, Deliverydate
, Description
, AddressId
, AccountId
, DeliverToName
, AddressLine1
, AddressLine2
, PostCode
, City
, State
, Country
, EmailAddress
)
select lower(to_char(sor.sor_OrderID)) Orderid
,      lower(to_char(sor.sor_Ordernumber))    OrderNumber
,      sor.sor_OrderDate      OrderDate
,      sor.sor_DeliveryDate   Deliverydate
,      left (sor.sor_Description, 50)    Description
,      lower(to_char(sor.sor_DeliveryAddress)) AddressId
,      lower(to_char(sor.sor_DeliverTo))       AccountId
,      left (sor.sor_DeliverToName, 50)          DeliverToName
,      left (sor.ads_AddressLine1, 50)
,      sor.ads_AddressLine2
,      sor.ads_Postcode
,      sor.ads_City
,      sor.ads_State
,      sor.ads_Country
,      sor.con_Email
from   sor@inmemorystorage

create or replace table sle@inmemorystorage
as 
select sle.*
from   sor@inmemorystorage sor
join   exactonlinerest..salesorderLines@eol sle
on     sle.orderid = sor.sor_orderid

insert into PHTestOrderLines@sql
( OrderLineID
, OrderID
, OrderNumber
, OrderLineNumber
, ItemID
, ItemCode
, Description
, Quantity
)
select lower(to_char(sle.ID))
,      lower(to_char(sle.OrderID))
,      lower(to_char(sle.OrderNumber))
,      sle.LineNumber
,      lower(to_char(sle.Item))
,      sle.ItemCode
,      sle.Description
,      sle.Quantity
from  sle@inmemorystorage

Dank voor het melden. De logica van de nieuwe zogenaamde “mandatory filtering” vanuit Exact Online API’s is wat apart. Onze implementatie van de logica in de engine heeft nog wat kinderziekten.

Een nieuwe versie deze week of begin volgende week zal dat oplossen.

Voor nu probeer s.v.p. eens toe te voegen:

and   sor.created is not null

zodat de where-clause wordt:

where  sor.DeliveryDate between trunc(sysdate)-40 and trunc(sysdate)
and    sor.DeliveryStatus = 12
and    sor.warehousecode = 1
and    sor.created is not null

Helpt deze workaround?

Nee helaas, deze work-around resulteert in dezelfde foutmelding

Dank voor proberen. De Invantive SQL optimizer optimaliseert het criterium waarschijnlijk weg: een verplicht veld is altijd not null.

Advies is te wachten tot de nieuwe release er is als dat kan. Voor morgenvroeg zal meer duidelijkheid zijn over de datum van beschikbaarheid hiervan.

Ik heb nog even verder getest.
Als ik de where-clause aanpas naar

where  sor.DeliveryStatus = 12

werkt het wel.
Zodra ik ook maar 1 AND toevoeg krijg ik de foutmelding zoals besproken.
(ik had overigens nu even de deliverystatus genomen als variabele omdat de deliverydate natuurlijk alles orders met alles statussen teruggeeft)

Deze mandatory filtering is dan te omzeilen als volgt:

create or replace table sor@inmemorystorage
as
select sor.* prefix with 'sor_'
,      ads.* prefix with 'ads_'
,      con.* prefix with  'con_'
from   ( select * 
         from   exactonlinerest..SalesOrders@eol sor
         where  sor.DeliveryStatus = 12
       )
join   exactonlinerest..addresses@eol ads
on     ads.id = sor.deliveryaddress
join   exactonlinerest..Contacts@eol con
on     con.account = sor.Invoiceto
where  sor.DeliveryDate between trunc(sysdate)-40 and trunc(sysdate)
--and    sor.DeliveryStatus = 12
and    sor.warehousecode = 1
order 
by     sor.ordernumber 

Het filter op DeliveryStatus is nu in een aparte query gezet die de optimizer op dit moment apart laat berekenen. Mocht het onverhoopt toch geoptimaliseerd worden, dan doorbreekt dit het zeker:

create or replace table avoidmandatoryfilterbug@inmemorystorage
as
select * 
from   exactonlinerest..SalesOrders@eol sor
where  sor.DeliveryStatus = 12

create or replace table sor@inmemorystorage
as
select sor.* prefix with 'sor_'
,      ads.* prefix with 'ads_'
,      con.* prefix with  'con_'
from   avoidmandatoryfilterbug@inmemorystorage sor
join   exactonlinerest..addresses@eol ads
on     ads.id = sor.deliveryaddress
join   exactonlinerest..Contacts@eol con
on     con.account = sor.Invoiceto
where  sor.DeliveryDate between trunc(sysdate)-40 and trunc(sysdate)
--and    sor.DeliveryStatus = 12
and    sor.warehousecode = 1
order 
by     sor.ordernumber 

Hier is mooi zichtbaar dat de mandatory filtering eigenlijk voorbijgaat aan zijn doel van beperken API-gebruik. Er worden nu meer API-calls gedaan dan noodzakelijk. Het zal op zich meevallen; misschien het dubbele of misschien paar x%, waarschijnlijk niet 100x zoveel. In mijn ogen is mandatory filtering een slecht ontwerp waarbij geen rekening is gehouden met menselijk ontwijkend gedrag en juist soms slechtere prestaties omdat de implementatie beter kan.

Zou deze uitgeprobeerd kunnen worden?

Werkt perfect!

Inderdaad een mooi voorbeeld van onnodig toegevoegde eisen.
Dank voor je hulp.

1 like

2 berichten zijn gesplitst naar een nieuw topic: Performance Exact Online query