Diğer dersleri http://selimkaratas.com.tr/oracle-11g-r2-egitimi-ders-notlari adresinden bulabilirsiniz.
4. Manipulating Large Data Sets
Using Subqueries to Manipulate Data ( Verileri işlemek için subquery Kullanımı)
SELECT department_name, city
FROM departments
NATURAL JOIN (SELECT l.location_id, l.city, l.country_id
FROM locations l
JOIN countries c
ON(l.country_id = c.country_id)
JOIN regions USING(region_id)
WHERE region_name = 'Europe');
-- 3 join yöntemini de kullanıyoruz
Subquery Kullanarak Insert Yapma
INSERT INTO ( SELECT location_id, city, country_id
FROM locations
WHERE country_id IN
(SELECT country_id
FROM countries
NATURAL JOIN regions
WHERE region_name = 'Europe'))
VALUES (3600, 'Washington', 'US');
/* where şartımızda Europe yazmasına rağmen insert işlemini yapmıştır bu gibi sorunları önlemek için özel bir keyword kullanacağız */
INSERT INTO ( SELECT location_id, city, country_id
FROM locations
WHERE country_id IN
(SELECT country_id
FROM countries
NATURAL JOIN regions
WHERE region_name = 'Europe')
WITH CHECK OPTION )
VALUES (3600, 'Washington', 'US');
--WITH CHECK OPTION ile veri tutarlılığı sağlarız
INSERT VE UPDATE İŞLEMLERİNDE DEFAULT KULLANIMI
INSERT INTO departments (department_id, department_name, manager_id) VALUES (300, 'İstatistikçi', DEFAULT); -- boş alanlara default değer(null) atadık
UPDATE departments SET manager_id = DEFAULT WHERE department_id = 110; --110 numaralı departman müdürünü default yaptık.
Önce 110 numaralı departmana bir bakalım:
Update işleminden sonra ise:
Görüldüğü gibi manager_id = null oldu.
Başka Tablodan Dataları Almak
INSERT INTO sales_rep(id, name, salary, comm) SELECT employee_id, last_name, salary, commission_pct FROM employees WHERE job_id LIKE '%REP%'; -- sales_rep tablosunu yarattıktan sonra insert işlemi yapabiliriz. tablonun varlığını kontrol ettikten sonra işlemi yapıyoruz. -- employees tablosunda job_id'si içinde 'rep' geçenlerin bilgilerini alıp sales_rep tablosuna kopyalıyoruz.
select * from sales_rep;
Multitable INSERT
Biz daha önce insert işlemini bir tablo için yapıyorduk. Burada birden fazla tabloya tek sorgu ile insert yapacağız.
INSERT ALL
Tek tek insert yapmak yerine insert all ile tek sorguda bu işlemi yapabiliriz.
Eğer tablolar yoksa
create table sal_history (empid number(5), hiredate date, sal number(8));
create table mgr_history (empid number(5), mgr number(5), sal number(8));
ile tabloları yaratabiliriz.
Daha sonra insert işlemini yapıyoruz.
INSERT ALL INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL, manager_id MGR FROM employees WHERE employee_id > 200; -- employee_id'leri 200'den büyük olanları tablolarımıza insert ediyoruz
select * from sal_hıstory;
select * from mgr_hıstory;
create table emp_history (empid number(5), hiredate date, sal number(8));
create table emp_sales(empid number(5), comm number(2,2), sal number(8));
insert all when hiredate < '01-OCA-96' then into emp_history values(empid, hiredate, sal) when comm is not null then into emp_sales values(empid, comm, sal) select employee_id empid, hire_date hiredate, commission_pct comm, salary sal from employees;
--yukarıda uyan herşeyi getirir ancak bu örnekte belirli şartlara göre insert yapar.
select * from emp_hıstory;
select * from emp_sales;
INSERT FIRST: Aynı anda birden çok şarta uyuyorsa kim yukarıda ise ona insert yap.
create table sal_low (empid number(5), last_name varchar2(15), sal number(8));
create table sal_mid (empid number(5), last_name varchar2(15), sal number(8));
create table sal_high (empid number(5), last_name varchar2(15), sal number(8));
INSERT FIRST WHEN salary < 5000 THEN INTO sal_low VALUES (employee_id, last_name, salary) WHEN salary between 5000 and 10000 THEN INTO sal_mid VALUES (employee_id, last_name, salary) ELSE INTO sal_high VALUES (employee_id, last_name, salary) SELECT employee_id, last_name, salary FROM employees -- maaşları aralıklarına göre uygun tablolara dağıtır. -- insert all bütün tablolara insert first şarta uyan tablolara insert yapar.
select * from sal_low;
select * from sal_mid;
select * from sal_high;
CREATE TABLE SALES_INFO2( EMPLOYEE_ID NUMBER(6), WEEK NUMBER(2), SALES NUMBER(8,2));
INSERT ALL INTO sales_info2 VALUES (employee_id,week_id,sales_MON) INTO sales_info2 VALUES (employee_id,week_id,sales_TUE) INTO sales_info2 VALUES (employee_id,week_id,sales_WED) INTO sales_info2 VALUES (employee_id,week_id,sales_THUR) INTO sales_info2 VALUES (employee_id,week_id,sales_FRI) SELECT EMPLOYEE_ID,week_id,sales_MON,sales_TUE,sales_WED,sales_THUR,sales_FRI from sales_source_data;
SELECT * FROM sales_ınfo2;
Pivoting INSERT
Bilgiyi tek satır içinde depolamışsa biz bunları birden fazla satır ve dikey formatlı hale getiriyoruz.
CREATE TABLE SALES_SOURCE_DATA( EMPLOYEE_ID NUMBER(6), WEEK_ID NUMBER(2), SALES_MON NUMBER(8,2), SALES_TUE NUMBER(8,2), SALES_WED NUMBER(8,2), SALES_THUR NUMBER(8,2), SALES_FRI NUMBER(8,2));
INSERT INTO SALES_SOURCE_DATA VALUES (117,6,1000,2000,3000,4000,5000);
SELECT * FROM SALES_SOURCE_DATA;
MERGE Statement: Bu işlemlerde hem update, hem insert, hem de delete işlemi tek komut içerisinde yapılabilir. İstediğimiz şekilde DML komutları kullanabiliriz.
CREATE TABLE bonuses (employee_id NUMBER, bonus NUMBER DEFAULT 100);
INSERT INTO bonuses(employee_id) (SELECT e.employee_id FROM employees e, sales_rep s WHERE e.employee_id = s.id GROUP BY e.employee_id);
SELECT * FROM bonuses;
MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*0.1) WHERE (S.salary <= 8000); -- iki tabloda da employee_id eşleşiyorsa update yaparız. -- employee_id'ler eşleşmiyorsa insert işlemi yaparız -- salary > 8000 olanları delete ediyoruz.
SELECT * FROM bonuses;
Flashback Version Query : Satırlar için elde edebildiği maksimum time periyodu içinde değişen değerleri verir.
SELECT salary FROM employees WHERE employee_id = 117; -- update öncesi : 2800 -- update sonrası: 3220
UPDATE employees SET salary = salary * 1.15 WHERE employee_id = 117;
COMMIT; -- commit yaptığımız için normalde eski maaşına erişemeyiz ancak özel bir sorgulama ile bu konuda bilgi sahibi olabiliriz
SELECT salary FROM employees VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE WHERE employee_id = 117; -- sorgusu ile eski ve yeni maaşlarını görebiliriz.
ile version_starttime and versions_endtime değişim zamanlarını verir.



















