ABAP’ta veritabanından veri çekmenin temel yolu Open SQL’dir. “Open” denmesinin sebebi; ABAP’ın farklı veritabanlarında (HANA, Oracle, MSSQL vb.) aynı sözdizimiyle çalışabilmesidir. Bu yazıda en temel ve en çok kullanılan Open SQL konularını örneklerle göreceğiz.
SELECTile veri çekmeSELECT SINGLEne zaman kullanılır?INTO/INTO TABLEWHEREfiltreleriUP TO n ROWSveORDER BY- Basit
JOIN - En sık yapılan hatalar (özellikle
sy-subrc,SELECT SINGLE,FOR ALL ENTRIES)
Örnek tablolar
Örneklerde SAP standart tablolarından bazılarını kullanacağız:
KNA1: Müşteri genel verileriVBAK: Satış belgesi başlıkVBAP: Satış belgesi kalem
Sen kendi sisteminde farklı tablolarla da aynı mantığı uygulayabilirsin.
1) Tek satır okuma: SELECT SINGLE
SELECT SINGLE genelde “tek kayıt” çekmek için kullanılır. Ama en kritik nokta şudur:
- Gerçekten tek kayıt geleceğinden eminsen (ör. primary key ile) uygundur.
- Aksi halde “rastgele bir satır” döndürebilir (özellikle
ORDER BYyoksa).
REPORT z_demo_open_sql_01.
DATA: ls_kna1 TYPE kna1.
SELECT SINGLE *
FROM kna1
INTO @ls_kna1
WHERE kunnr = @'0000001000'.
IF sy-subrc = 0.
WRITE: / ls_kna1-kunnr, ls_kna1-name1.
ELSE.
WRITE: / 'Kayit bulunamadi'.
ENDIF.
İpucu: sy-subrc = 0 → kayıt bulundu demektir.
2) Birden fazla satır: SELECT … INTO TABLE
Birden fazla kayıt çekmek için çoğu zaman en pratik yöntem INTO TABLE kullanmaktır.
REPORT z_demo_open_sql_02.
DATA: lt_kna1 TYPE TABLE OF kna1.
SELECT *
FROM kna1
INTO TABLE @lt_kna1
UP TO 20 ROWS.
WRITE: / 'Kayit sayisi:', lines( lt_kna1 ).
Not: Gerçek hayatta SELECT * yerine genelde sadece ihtiyacın olan alanları seçmek daha iyi bir pratiktir.
3) Sadece gerekli alanları seçmek (Performans için iyi alışkanlık)
REPORT z_demo_open_sql_03.
TYPES: BEGIN OF ty_cust,
kunnr TYPE kna1-kunnr,
name1 TYPE kna1-name1,
land1 TYPE kna1-land1,
END OF ty_cust.
DATA lt_cust TYPE TABLE OF ty_cust.
SELECT kunnr, name1, land1
FROM kna1
INTO TABLE @lt_cust
UP TO 20 ROWS.
LOOP AT lt_cust INTO DATA(ls_cust).
WRITE: / ls_cust-kunnr, ls_cust-name1, ls_cust-land1.
ENDLOOP.
4) WHERE ile filtreleme
WHERE kısmı veritabanında filtre uygular. Bu genelde internal table üzerinde filtrelemeye göre daha iyidir.
REPORT z_demo_open_sql_04.
DATA lt_kna1 TYPE TABLE OF kna1.
SELECT kunnr, name1, land1
FROM kna1
INTO TABLE @lt_kna1
WHERE land1 = @'TR'
UP TO 50 ROWS.
WRITE: / 'TR musterileri:', lines( lt_kna1 ).
5) Selection Screen ile birlikte kullanma (IN ile çok pratik)
REPORT z_demo_open_sql_05.
SELECT-OPTIONS: s_kunnr FOR kna1-kunnr.
DATA lt_kna1 TYPE TABLE OF kna1.
START-OF-SELECTION.
SELECT kunnr, name1
FROM kna1
INTO TABLE @lt_kna1
WHERE kunnr IN @s_kunnr
UP TO 50 ROWS.
WRITE: / 'Kayit sayisi:', lines( lt_kna1 ).
6) Sıralama ve limit: ORDER BY + UP TO n ROWS
“İlk 10 kayıt” gibi bir şey istiyorsan, çoğu zaman ORDER BY ile birlikte kullanmak gerekir.
REPORT z_demo_open_sql_06.
DATA lt_kna1 TYPE TABLE OF kna1.
SELECT kunnr, name1
FROM kna1
INTO TABLE @lt_kna1
WHERE land1 = @'TR'
ORDER BY kunnr
UP TO 10 ROWS.
LOOP AT lt_kna1 INTO DATA(ls_kna1).
WRITE: / ls_kna1-kunnr, ls_kna1-name1.
ENDLOOP.
7) Basit JOIN örneği (VBAK + VBAP)
Satış belgesi başlığı (VBAK) ile kalemleri (VBAP) birleştirelim.
REPORT z_demo_open_sql_join_01.
TYPES: BEGIN OF ty_sales,
vbeln TYPE vbak-vbeln,
erdat TYPE vbak-erdat,
posnr TYPE vbap-posnr,
matnr TYPE vbap-matnr,
kwmeng TYPE vbap-kwmeng,
END OF ty_sales.
DATA lt_sales TYPE TABLE OF ty_sales.
SELECT a~vbeln,
a~erdat,
b~posnr,
b~matnr,
b~kwmeng
FROM vbak AS a
INNER JOIN vbap AS b
ON b~vbeln = a~vbeln
INTO TABLE @lt_sales
UP TO 20 ROWS.
WRITE: / 'Kayit sayisi:', lines( lt_sales ).
İpucu: Join yaparken mümkünse WHERE ile belge aralığı / tarih gibi filtre koymak daha gerçekçi olur.
8) En sık yapılan hatalar
Hata 1: SELECT SINGLE ile “hangi satır geldiği” belirsiz
Primary key ile filtrelemezsen “tek satır” garanti değildir. Bu yüzden:
- Ya key alanlarını kullan,
- Ya da
UP TO 1 ROWS+ORDER BYdüşün.
Hata 2: SELECT sonrası sy-subrc kontrolünü unutmak
SELECT SINGLEsonrasısy-subrckontrol etINTO TABLEsonrası geneldelines( itab )ile kontrol pratik
Hata 3: FOR ALL ENTRIES (FAE) tuzağı
FOR ALL ENTRIES çok kullanılan ama yeni başlayanların en çok hata yaptığı konudur. En kritik kural:
- FAE internal table boşsa, sonuç beklenenden farklı olabilir (bazı senaryolarda “çok fazla kayıt” dönebilir).
Bu yüzden önce boş kontrolü yap:
IF lt_keys IS NOT INITIAL.
SELECT ...
FROM ...
INTO TABLE @lt_result
FOR ALL ENTRIES IN @lt_keys
WHERE field = @lt_keys-field.
ENDIF.
Not: Başlangıç seviyesi için FAE’yi detaylandırmayı ayrı bir yazıda yapmak daha iyi olur.
Sonuç
Bu yazıda Open SQL’in temelini oluşturan yapıları gördük: tek kayıt okuma, tabloya çoklu kayıt çekme, filtreleme, sıralama-limit ve basit join. Open SQL’i iyi öğrenmek ABAP’ta “işin omurgası”dır.
ABAP’ta değişken isimlendirme kuralları için bu yazıyı okuyabilirsiniz.
![]()