1) Hatasiz derlenmis bir SQL komutunda tüm objelerin veritabaninda geçerli oldugu bilinir,
2) Hatasiz derlenmis bir SQL komutunda tüm yetkilendirmelerin yerli yerinde oldugu bilinir.
3) Statik SQL komutlarinin sagladigi performans dinamik SQL’e göre daha üstündür.
Bu avantajlara baktigimizda dinamik SQL’I ancak, static SQL komutlariyla basaramadigimiz islerde veya static SQL komutlarinin kullanissiz kaldigi durumlarda kullanmayi tercih etmeliyiz.Her ne kadar statik SQL in kisitlamalari olsa da performans bakimindan dinamik SQL e nazaran üstündür. Içinizdeki soruyu duyar gibiyim, “e pekala neden dinamik SQL ?”…
Neden Dinamik SQL ?
Programlarinizda bazi anlarda yazacaginiz SQL komutlarinin full içerigini bilmeyebilirsiniz. Yani SQL sorgunuz, kullanicidan gelecek degisik input degerlerine gore sekillenme ihtiyaci duyabilir. Lafi karistirmadan hemen bir örnek verelim;
Bir datawarehouse ortaminiz var ve siz bu ortamdaki bir raporlama modülünüzdeki tablo isimlerini derlendigi tarihe gore atamak istiyorsunuz. Mesela INV_01_1997, INV_04_1997, INV_07_1997, INV_10_1997 gibi. Böyle durumlarda raporlama modülünüzde dinamik SQL kullanarak tablolarinizi çalisma zamaninda ‘create’ edebilirsiniz.
Veya programinizda bir listeleme modülü var ve siralamayi kullanicinin belirlemesini istiyorsunuz. Böyle bir durumda ‘order by’ fonksiyonu degisken olacaktir. Yani kullanici hangi kritere gore siralama yapmak istiyorsa ‘order by’ o kritere gore sekillenecektir. Böyle bir durumda da dinamik SQL kullanabilirsiniz.
PL/SQL Bloklari Içinde DDL ve SCL Kullanimi
PL/SQL içinde su tipleri static SQL’ e tercihen kullanabiliriz :
- DDL(Data Definition Language) cümleleri. ‘Create’, ‘Drop’, ‘Grant’, ‘Revoke’ gibi…
- SCL(Session Control Language) cümleleri. ‘Alter Session’, ‘Set Role’ gibi..
Bir örnek verecek olursak :
CREATE TYPE t_emp AS OBJECT (id NUMBER, name VARCHAR2(20))
/
CREATE TYPE t_emplist AS TABLE OF t_emp
/
CREATE TABLE dept_new (id NUMBER, emps t_emplist)
NESTED TABLE emps STORE AS emp_table;
INSERT INTO dept_new VALUES (
10,
t_emplist(
t_emp(1, 'SCOTT'),
t_emp(2, 'BRUCE')));
DECLARE
deptid NUMBER;
ename VARCHAR2(20);
BEGIN
EXECUTE IMMEDIATE 'SELECT d.id, e.name
FROM dept_new d, TABLE(d.emps) e -- not allowed in static SQL
-- in PL/SQL
WHERE e.id = 1'
INTO deptid, ename;
END;
Dinamik SQL Kullanim Alanlari
- Kullaniciya çalisma zamaninda sorgu seçimi veya kritere gore siralama v.s islem seçenegi sunan uygulamalar,
- Çalisma aninda veri girisi veya optimizasyon seçenegi sunan uygulamalar,
- Veritabanindaki tablo tanimlamalarinin (DDL statements) sürekli degisken oldugu uygulamalar,
- Istege ve ihtiyaca gore çalisma aninda create edilen tablo vb. objeler içeren uygulamalar.
Konunun basinda vermis oldugumuz datawarehouse örnegine bakarsak, tablo tanimini normalde biliyoruz fakat ismini çalisma aninda vermek istiyoruz. Dinamik SQL bu problemi çözüyor.
CREATE OR REPLACE PROCEDURE query_invoice(
month VARCHAR2,
year VARCHAR2) IS
TYPE cur_typ IS REF CURSOR;
c cur_typ;
query_str VARCHAR2(200);
inv_num NUMBER;
inv_cust VARCHAR2(20);
inv_amt NUMBER;
BEGIN
query_str := 'SELECT num, cust, amt FROM inv_' || month ||'_'|| year
|| ' WHERE invnum = :id';
OPEN c FOR query_str USING inv_num;
LOOP
FETCH c INTO inv_num, inv_cust, inv_amt;
EXIT WHEN c%NOTFOUND;
-- process row here
END LOOP;
CLOSE c;
END;
/