19 Eylül 2014 Cuma

Query nesneleri (Queries)-4 : Gelişmiş Sorgulamalar

Daha önceki yazılarımda Query nesnelerinden bahsetmiştim.
Bir Query’ye kriterler eklemek için QueryBuildRange nesnelerinin kullanılması gerektiğini de paylaşmıştım. Ancak herbir QueryBuildRange nesnesi standartta tek bir alan için tanımlanır. Ve değer atamak için kullandığımız yardımcı classlar veya fonksiyonlar bize bir noktaya kadar yardım edebilir. Bu da değer ya da aralık atama şeklinde gerçekleşir. (tek bir değer, en büyük değer, değil operatörü, tarih aralığı gibi)
Ancak gerçek hayatta sorgularımız çok daha karmaşık olabilir. Kriterlemiz tek bir alanda toplanamayıp farklı alanların ve – veya operatörleri ile birleştirilmesinden oluşabilir.
Örneğin müşteriler tablosunda müşteri grubu Yurtiçi olanlar ya da para birimi Türk Lirası olanlar gibi. Tabi bu değerlerin sabit olmayıp çalışma zamanında kullanıcıdan alınacağını varsayalım. Bu durumda iki farklı alana veya (OR) operatörü ile aralık eklemek gerekir.
Ya da uygulamamızda müşteri grubu yurt içi ya da yurtuiçi kurumsal olanları sorgulamak istersek aynı alanda veya operatörü (OR) kullanarak bir kriter belirtmemiz gerekir. Peki bunu nasıl yapabiliriz?
QueryBuildRange nesneleri ve OR operatörü
Yukarda da bahsettiğim gibi, bir Query’ye eklenen tüm QueryBuildRange’ler birbirleri ile AND operatörü ile bağlanırlar. Ancak biz bunu her zaman istemeyiz. Standart nesnelerin yardımının bittiği yerde gelişmiş (yada genişletilmiş) sorgulamayöntemleri devreye girer. Query nesnelerinde gelişmiş sorgulama yöntemleri kullanılarak OR operatörünü kullanmanın iki yöntemi vardır.

1. Aynı alana OR operatörü ile kriter eklemek:
Sorgumuzda müşteriler tablsounda para birimi Amerikan Doları(USD) olanlarla Kanada Doları (CAN) olanları görmek istediğimizi varsayalım. Bu durumda aynı alana arka arkaya birden fazla kez range tanımlayıp atama yaptığımızda AX yorumlayıcısı bunları OR olarak değerlendirmektedir.
Püf noktası : QueryBuildRange nesnesi kullanmadan birden çok kez tanımlama ve atama yapılır.
Ör :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
static void QueryWithOr1(Args _args)
{
CustTable               custTable;
Query                   q;
QueryRun                qr;
QueryBuildDataSource    qbdsCustTable;
;
setPrefix("while select ile");
while select custTable
    where custTable.Currency == "USD"
        || custTable.Currency == "CAD"
{
    info(strFmt("%1 %2 %3",
        custTable.AccountNum,
        custTable.Name,
        custTable.Currency));
}
setPrefix("query ile");
q               = new Query();
qbdsCustTable   = q.addDataSource(tableNum(CustTable));
qbdsCustTable.addRange(fieldNum(CustTable, Currency)).value(sysQuery::value("USD"));
qbdsCustTable.addRange(fieldNum(CustTable, Currency)).value(sysQuery::value("CAD"));
qr              = new QueryRun(q);
while (qr.next())
{
    custTable = qr.get(tableNum(CustTable));
    info(strFmt("%1 %2 %3",
    custTable.AccountNum,
    custTable.Name,
    custTable.Currency));
}
}
2. Birden fazla alana OR operatörü ile kriter eklemek
Eğer query nesnenizi incelerseniz, queryBuildDataSource nesnelerinin uygun şekilde biçimlendirilmiş SQL cümlecikleri içerdiğini görebiliriz. Bu cümleciklere range eklediğimizde bu cümlecikte alan adları, operatörler ve değerlerin bulunduğunu görebiliriz. Ayrıca her kriterin bir parantez içine alındığını da görebiliriz. Bu detaydan bahsetmemin nedeni ise basit; temelde aynı cümleciği bizim de oluşturmamız gerekecek.
Püf noktası 1 : QueryBuildRange nesnesinin hangi alan için tanımlandığı önemli değildir.
Püf noktası 2 : Metin tipindeki değerler için çift tırnak( ” ) kullanmak zorunludur. Bu nedenle strFmt için tek tırnak kullanmak ( ‘ )gerekir.
Püf noktası 3 : Her bir kriter grubu paranteze alınmalı, tüm kriterler de ayrıca paranteze alınmalıdır.
Püf noktası 4 : Tarih tipindeki değerler için date2StrXpp metodunu kullanın.
Püf noktası 5 : Enumlar için any2Int metodunu kullanın.
Ör :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
static void QueryWithOr2(Args _args)
{
CustTable               custTable;
Query                   q;
QueryRun                qr;
QueryBuildDataSource    qbdsCustTable;
QueryBuildRange         qbr;
;
setPrefix("while select ile");
while select custTable
    where custTable.CustGroup == "10"
       || custTable.Currency == "CAD"
{
    info(strFmt("%1 %2 %3 %4",
    custTable.AccountNum,
    custTable.Name,
    custTable.CustGroup,
    custTable.Currency));
}
setPrefix("query ile");
q               = new Query();
qbdsCustTable   = q.addDataSource(tableNum(CustTable));
//Range'i hangi alana bağladığımızın önemi yok. Sadece dataSource'a bağlamamız gerekir.
qbr             = qbdsCustTable.addRange(fieldNum(CustTable, DataAreaId));
qbr.value(strfmt('((%1 = "%2") || (%3 = "%4"))',
    fieldstr(CustTable,CustGroup),
    queryvalue("10"),
    fieldstr(CustTable,Currency),
    queryvalue("CAD")));
qr              = new QueryRun(q);
while (qr.next())
{
    custTable = qr.get(tableNum(CustTable));
    info(strFmt("%1 %2 %3 %4",
    custTable.AccountNum,
    custTable.Name,
    custTable.CustGroup,
    custTable.Currency));
}
}
Ali Güç - 2014

Hiç yorum yok:

Yorum Gönder