Bu bir köprü dersiTarayıcıda PL/SQL yorumlayıcısı yok; bu kodlar çalışmaz, denetlenmez. Hedef, ilanda ya da mevcut kodda gördüğünde okuyabilmek. Yazmayı öğrenmek için ücretsiz Oracle ortamı gerekir. Blok, tip ve basit imleç için Oracle PL/SQL ile programlama dersine bak. Yazımlar genel bilgiye dayanır, Oracle belgesi bu dersi yazarken açılamadı.
| İş | T-SQL | PL/SQL |
|---|---|---|
| Çıkış parametresi | @p INT OUTPUT | p OUT NUMBER, iki yönlü IN OUT |
| Sonuç kümesi döndürme | SELECT yeter | OUT SYS_REFCURSOR |
| Dinamik SQL | sp_executesql | EXECUTE IMMEDIATE ... USING |
| Toplu okuma | Küme tabanlı SELECT | BULK COLLECT INTO |
| Toplu yazma | Küme tabanlı DML | FORALL |
| Hata | THROW | RAISE_APPLICATION_ERROR(-20001, ...) |
CREATE OR REPLACE PROCEDURE zam_yap (p_dept IN NUMBER, p_oran IN NUMBER, p_adet OUT NUMBER) AS
TYPE t_id IS TABLE OF employees.emp_id%TYPE;
v_id t_id;
BEGIN
SELECT emp_id BULK COLLECT INTO v_id FROM employees WHERE dept_id = p_dept;
FORALL i IN 1 .. v_id.COUNT
UPDATE employees SET salary = salary * (1 + p_oran) WHERE emp_id = v_id(i);
p_adet := SQL%ROWCOUNT;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
/
Neden BULK COLLECT ve FORALL?
PL/SQL motoru ile SQL motoru ayrıdır; döngüde her satırda iki motor arasında geçiş olur. Bu iki yazım geçişi topluca yapar, büyük hacimde belirgin hızlandırır. Tek SQL ifadesiyle yazılabiliyorsa o yine en iyisidir.
-- Açık imleç: OPEN, FETCH, CLOSE
DECLARE
CURSOR c IS SELECT name, price FROM products WHERE category = 'Kitap';
v c%ROWTYPE;
BEGIN
OPEN c;
LOOP
FETCH c INTO v;
EXIT WHEN c%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v.name);
END LOOP;
CLOSE c;
END;
/
-- Dinamik SQL, bağlı değişkenle
EXECUTE IMMEDIATE 'UPDATE products SET stock = 0 WHERE product_id = :1' USING v_id;