0Pricing
R Academy · Ders

Parametreli Sorgular ve İşlemler

Parametreleri güvenle aktarın ve R'de çok adımlı veritabanı işlemlerini yönetin.

Parametreli Sorgular ve İşlemler, CoddyKit'te ücretsiz bir R Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, R Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. R Academy kursu toplamda 4 dersten oluşur.

Parametreli Sorgular Neden Kullanılır?

Kullanıcı girdisi doğrudan bir SQL dizesine yapıştırıldığında saldırgan kötü amaçlı SQL kodu enjekte edebilir. Parametreli sorgular, SQL yapısını veri değerlerinden ayırır; böylece enjeksiyon saldırılarını olanaksız hâle getirirken kodunuzu da daha temiz ve okunaklı yapar.

library(DBI)

# DANGEROUS: string concatenation (SQL injection risk!)
user_input <- "'; DROP TABLE users; --"
# bad_sql <- paste0("SELECT * FROM users WHERE name = '", user_input, "'")
# dbGetQuery(con, bad_sql)   <- NEVER do this

# SAFE: parameterized query
# dbGetQuery(con, 'SELECT * FROM users WHERE name = $1',
#            params = list(user_input))

cat('Parameterized queries prevent SQL injection')

Parametrelerle dbGetQuery()

dbGetQuery(), bir SELECT ifadesini çalıştırır ve sonuçları veri çerçevesi olarak döndürür. Yer tutuculara değer bağlamak için bir params listesi aktarın. Yer tutucu söz dizimi sürücüye göre değişir: PostgreSQL için $1, SQLite/MySQL için ?.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbWriteTable(con, 'employees', data.frame(
  name       = c('Alice', 'Bob', 'Carol'),
  department = c('Engineering', 'Marketing', 'Engineering'),
  salary     = c(90000, 75000, 95000)
))

# Parameterized SELECT — SQLite uses ?
result <- dbGetQuery(
  con,
  'SELECT name, salary FROM employees WHERE department = ?',
  params = list('Engineering')
)
print(result)

dbDisconnect(con)

dbExecute() — INSERT, UPDATE, DELETE

dbExecute(), verileri değiştiren SQL ifadelerini (INSERT, UPDATE, DELETE) çalıştırır ve etkilenen satır sayısını döndürür. Değerleri güvenli biçimde bağlamak için params kullanın. Yazma işlemleri için doğru işlev budur.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbWriteTable(con, 'users', data.frame(
  id     = 1:3,
  name   = c('Alice', 'Bob', 'Carol'),
  active = c(TRUE, FALSE, TRUE)
))

# Safe UPDATE with parameters
rows_affected <- dbExecute(
  con,
  'UPDATE users SET active = ? WHERE id = ?',
  params = list(TRUE, 2)
)
cat('Rows updated:', rows_affected, '\n')

# Verify
result <- dbGetQuery(con, 'SELECT * FROM users WHERE id = 2')
cat('Bob active:', result$active)

dbDisconnect(con)

Tek Sorguda Birden Çok Parametre

Tüm parametreleri params listesinde sağlayarak birden çok parametre bağlayabilirsiniz. Bunlar, SQL dizesindeki yer tutuculara (? veya $1, $2, ...) sırayla bağlanır. Liste öğelerinin sayısını her zaman yer tutucuların sayısıyla eşleştirin.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbWriteTable(con, 'products', data.frame(
  id    = 1:4,
  name  = c('Apple', 'Banana', 'Cherry', 'Date'),
  price = c(1.5, 0.8, 3.0, 5.0),
  stock = c(100, 200, 50, 30)
))

# Filter by two parameters
result <- dbGetQuery(
  con,
  'SELECT name, price FROM products WHERE price > ? AND stock > ?',
  params = list(1.0, 40)
)
print(result)

dbDisconnect(con)

Parametreli INSERT

Parametreli INSERT ifadeleri yeni kayıtları güvenli biçimde ekler. Her sütun değerini bir parametre olarak bağlayın. Toplu eklemeler için bunun yerine bir veri çerçevesiyle dbAppendTable() kullanın — daha hızlıdır ve DBI bağlama işlemini otomatik olarak yönetir.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE logs (level TEXT, message TEXT, ts TEXT)')

# Parameterized INSERT
dbExecute(
  con,
  'INSERT INTO logs (level, message, ts) VALUES (?, ?, ?)',
  params = list('INFO', 'User logged in', as.character(Sys.time()))
)

result <- dbGetQuery(con, 'SELECT * FROM logs')
print(result)

dbDisconnect(con)

dbBegin() ve dbCommit() — İşlemler

İşlem, birden çok SQL ifadesini tek bir atomik birimde gruplar: ya hepsi başarılı olur ya da hiçbiri gerçekleşmez. Başlatmak için dbBegin(), ardından tüm değişiklikleri birlikte kesinleştirmek için dbCommit() kullanın.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE accounts (id INTEGER, balance REAL)')
dbExecute(con, "INSERT INTO accounts VALUES (1, 1000), (2, 500)")

# Transfer 200 from account 1 to account 2
dbBegin(con)
  dbExecute(con, 'UPDATE accounts SET balance = balance - ? WHERE id = ?',
            params = list(200, 1))
  dbExecute(con, 'UPDATE accounts SET balance = balance + ? WHERE id = ?',
            params = list(200, 2))
dbCommit(con)

result <- dbGetQuery(con, 'SELECT * FROM accounts')
print(result)
dbDisconnect(con)

dbRollback() — İşlemi Geri Alma

Bir işlemdeki herhangi bir ifade başarısız olursa, dbBegin() çağrısından bu yana yapılan tüm değişiklikleri geri almak için dbRollback() çağırın. Bu, veritabanının tutarlı durumda kalmasını sağlar. dbBegin() çağrısını her zaman dbCommit() veya dbRollback() ile eşleştirin.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE orders (id INTEGER, amount REAL)')
dbExecute(con, 'INSERT INTO orders VALUES (1, 500)')

# Simulate a failed transaction
dbBegin(con)
tryCatch({
  dbExecute(con, 'UPDATE orders SET amount = ? WHERE id = ?',
            params = list(600, 1))
  stop('Simulated error during processing')  # something goes wrong
  dbCommit(con)
}, error = function(e) {
  dbRollback(con)
  cat('Transaction rolled back:', e$message, '\n')
})

# Amount is still 500 (rollback worked)
result <- dbGetQuery(con, 'SELECT * FROM orders')
cat('Amount after rollback:', result$amount)
dbDisconnect(con)

dbWithTransaction() — Daha Güvenli Yaklaşım

dbWithTransaction(), kod bloğunuzu otomatik olarak bir işlem içine alır. Blok başarılı olursa değişiklikleri kesinleştirir, herhangi bir hata oluşursa geri alır. Bu yaklaşım, dbBegin() / dbCommit() / dbRollback() çağrılarını elle yapmaktan daha temizdir ve hataya daha az açıktır.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE ledger (account TEXT, amount REAL)')
dbExecute(con, "INSERT INTO ledger VALUES ('Alice', 1000), ('Bob', 500)")

# Automatic transaction management:
dbWithTransaction(con, {
  dbExecute(con, "UPDATE ledger SET amount = amount - 100 WHERE account = 'Alice'",
            params = list())
  dbExecute(con, "UPDATE ledger SET amount = amount + 100 WHERE account = 'Bob'",
            params = list())
})
# Committed automatically on success

print(dbGetQuery(con, 'SELECT * FROM ledger'))
dbDisconnect(con)

İşlemler İçinde Hata Yönetimi

tryCatch() ile dbWithTransaction() işlevlerini birleştirmek, hataların temiz biçimde raporlanmasını sağlar. İç blok bir hata oluşturduğunda dbWithTransaction() otomatik olarak geri alma işlemi yapar; hata işleyiciniz de sorunu günlüğe yazabilir veya yeniden oluşturabilir.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE inventory (item TEXT, qty INTEGER)')
dbExecute(con, "INSERT INTO inventory VALUES ('Widget', 100)")

safe_update <- function(con, item, qty_change) {
  tryCatch(
    dbWithTransaction(con, {
      dbExecute(con,
        'UPDATE inventory SET qty = qty + ? WHERE item = ?',
        params = list(qty_change, item))
      cat('Updated', item, 'by', qty_change, '\n')
    }),
    error = function(e) cat('Failed (rolled back):', e$message, '\n')
  )
}

safe_update(con, 'Widget', -30)
print(dbGetQuery(con, 'SELECT * FROM inventory'))
dbDisconnect(con)

Performans İçin Toplu Ekleme

Bir döngüde çok sayıda satırı tek tek eklemek yavaştır. Daha iyi iki yaklaşım vardır: tüm veri çerçevesini tek seferde eklemek için dbAppendTable() kullanmak veya tek tek eklemeleri tek bir işlem içine almak — veritabanları disk yazma işlemlerini yalnızca sonunda kesinleştirir; bu nedenle işlem içindeki toplu ekleme, otomatik kesinleştirmeli eklemelerden çok daha hızlıdır.

library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
dbExecute(con, 'CREATE TABLE events (user_id INTEGER, action TEXT)')

# Fast: insert a whole data frame at once
new_events <- data.frame(
  user_id = c(101, 102, 103, 104),
  action  = c('login', 'view', 'purchase', 'logout')
)
dbAppendTable(con, 'events', new_events)

result <- dbGetQuery(con, 'SELECT COUNT(*) AS n FROM events')
cat('Rows inserted:', result$n)

dbDisconnect(con)

dbDisconnect() — Bağlantıları Her Zaman Kapatın

Veritabanı bağlantıları sunucudaki kaynakları tüketir. İşiniz bittiğinde her zaman dbDisconnect(con) çağırın. Bir işlevin başında on.exit(dbDisconnect(con)) kullanmak, hata oluşsa bile bağlantının kapanmasını sağlar.

library(DBI)

# Pattern: use on.exit to guarantee disconnection
run_query <- function(sql) {
  con <- dbConnect(RSQLite::SQLite(), ':memory:')
  on.exit(dbDisconnect(con), add = TRUE)  # always runs

  dbExecute(con, 'CREATE TABLE t (x INTEGER)')
  dbExecute(con, 'INSERT INTO t VALUES (1), (2), (3)')
  result <- dbGetQuery(con, sql)
  result  # con is closed automatically after return
}

df <- run_query('SELECT * FROM t WHERE x > 1')
cat('Rows:', nrow(df))
# on.exit fires after return — connection cleanly closed

Kısa Kontrol

İki ilişkili UPDATE ifadesini, ya ikisinin de başarılı olması ya da hiçbirinin veritabanını değiştirmemesi için gruplamanız gerekiyor. En iyi yaklaşım hangisidir?

Parametreli Sorgular ve İşlemler — Önemli Çıkarımlar

DBI ile R'de güvenli ve güvenilir veritabanı işlemleri:

  • Kullanıcı girdisini hiçbir zaman SQL dizelerine birleştirmeyin — her zaman params kullanın
  • dbGetQuery(con, sql, params = list(...)) — güvenli SELECT
  • dbExecute(con, sql, params = list(...)) — güvenli INSERT/UPDATE/DELETE
  • Yer tutucular: SQLite/MySQL için ?, PostgreSQL için $1 / $2
  • dbBegin() + dbCommit() + dbRollback() — elle işlem denetimi
  • dbWithTransaction(con, { ... }) — otomatik kesinleştirme/geri alma (tercih edilen yöntem)
  • dbAppendTable(con, 'tbl', df) — hızlı toplu ekleme
  • on.exit(dbDisconnect(con)) — bağlantıları her zaman kapatın
library(DBI)

con <- dbConnect(RSQLite::SQLite(), ':memory:')
on.exit(dbDisconnect(con), add = TRUE)

dbExecute(con, 'CREATE TABLE transfers (from_id INT, to_id INT, amount REAL)')

# Safe parameterized insert inside a transaction:
dbWithTransaction(con, {
  dbExecute(con,
    'INSERT INTO transfers (from_id, to_id, amount) VALUES (?, ?, ?)',
    params = list(1, 2, 250.00)
  )
})

result <- dbGetQuery(con, 'SELECT * FROM transfers')
cat('Transfer recorded:', result$amount)

Sıkça Sorulan Sorular

“Parametreli Sorgular ve İşlemler” dersi ücretsiz mi?

Evet — “Parametreli Sorgular ve İşlemler” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve R Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. R Academy kursu toplamda 4 dersten oluşur.

“Parametreli Sorgular ve İşlemler” dersinde ne öğreneceğim?

Parametreleri güvenle aktarın ve R'de çok adımlı veritabanı işlemlerini yönetin. R Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

R Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te R Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Parametreli Sorgular ve İşlemler” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu R Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her R Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. DBI ve RSQLite Temelleri
  2. PostgreSQL ve MySQL'e Bağlanma
  3. dbplyr: dplyr Sözdizimiyle SQL
  4. Parametreli Sorgular ve İşlemler
← R Academy Sayfasına Dön