stok uygulaması 20 Nisan
SQL Server’da StokDB veritabanını ve tablolarını oluşturmak.
Kategoriler Urunler
----------- -------
KategoriID (PK) ←── KategoriID (FK)
KategoriAdi UrunID (PK)
UrunAdi
Barkod
Fiyat
StokMiktari
EklenmeTarihi
SQL Script — SSMS veya Azure Data Studio’da çalıştırın
-- 1. Veritabanı oluştur
CREATE DATABASE StokDB;
GO
USE StokDB;
GO
-- 2. Kategoriler tablosu
CREATE TABLE Kategoriler (
KategoriID INT IDENTITY(1,1) PRIMARY KEY,
KategoriAdi NVARCHAR(100) NOT NULL
);
GO
-- 3. Ürünler tablosu
CREATE TABLE Urunler (
UrunID INT IDENTITY(1,1) PRIMARY KEY,
UrunAdi NVARCHAR(200) NOT NULL,
Barkod NVARCHAR(50) UNIQUE,
Fiyat DECIMAL(10,2) NOT NULL DEFAULT 0,
StokMiktari INT NOT NULL DEFAULT 0,
KategoriID INT FOREIGN KEY REFERENCES Kategoriler(KategoriID),
EklenmeTarihi DATETIME DEFAULT GETDATE()
);
GO
-- 4. Örnek kategoriler
INSERT INTO Kategoriler (KategoriAdi) VALUES
('Elektronik'),
('Gıda'),
('Giyim'),
('Kırtasiye'),
('Kozmetik');
GO
-- 5. Örnek ürünler
INSERT INTO Urunler (UrunAdi, Barkod, Fiyat, StokMiktari, KategoriID) VALUES
('Laptop', '8680001', 15000.00, 10, 1),
('Şeker 1kg', '8680002', 25.50, 50, 2),
('Beyaz Gömlek', '8680003', 350.00, 30, 3),
('Tükenmez Kalem', '8680004', 5.00,100, 4),
('Şampuan', '8680005', 45.00, 40, 5);
GO
-- 6. Kontrol sorgusu
SELECT u.UrunID, u.UrunAdi, u.Barkod, u.Fiyat, u.StokMiktari,
k.KategoriAdi, u.EklenmeTarihi
FROM Urunler u
JOIN Kategoriler k ON u.KategoriID = k.KategoriID;
Visual Studio’da projeyi kurmak ve SQL Server bağlantısını test etmek.
StokYonetimi/ ├── Forms/ │ ├── AnaSayfa.cs ← Ana menü │ ├── UrunListeFormu.cs ← Listeleme + Silme │ ├── UrunEkleFormu.cs ← Ekleme │ └── UrunGuncelleFormu.cs ← Güncelleme ├── Helpers/ │ └── DbHelper.cs ← Veritabanı bağlantı sınıfı └── Program.cs
PM> Install-Package Microsoft.Data.SqlClient
Helpers klasörü oluşturun, içine DbHelper.cs ekleyin
using Microsoft.Data.SqlClient;
namespace StokYonetimi.Helpers
{
public static class DbHelper
{
// ⚠️ Kendi sunucu adınıza göre değiştirin
private static readonly string ConnectionString =
"Server=.\\SQLEXPRESS; Database=StokDB; Trusted_Connection=True; TrustServerCertificate=True;";
public static SqlConnection GetConnection()
{
return new SqlConnection(ConnectionString);
}
}
}
Not: Sunucu adı için SSMS’te bağlandığınız adı kullanın.
Örnek: Server=BILGISAYAR-ADI\\SQLEXPRESS
AnaSayfa.cs formunun Load olayına ekleyin:
using Microsoft.Data.SqlClient;
using StokYonetimi.Helpers;
private void AnaSayfa_Load(object sender, EventArgs e)
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
MessageBox.Show("✅ Veritabanı bağlantısı BAŞARILI!", "Bağlantı Testi",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show("❌ Bağlantı hatası: " + ex.Message, "Hata",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Ana Sayfa Tasarımı (AnaSayfa.cs)
Ana Sayfa Tasarımı (AnaSayfa.cs)
Designer’da şu kontrolları ekleyin:
Kontrol Name Text
Label lblBaslik STOK YÖNETİM SİSTEMİ
Button btnUrunler 📋 Ürün Listesi
Button btnEkle ➕ Yeni Ürün Ekle
Button btnCikis 🚪 Çıkış
✅ Saat 2 Kontrol Listesi
WinForms projesi oluşturuldu
Microsoft.Data.SqlClient paketi yüklendi
DbHelper.cs oluşturuldu
Bağlantı testi başarılı
Ana sayfa tasarlandı
⏱️ 3. SAAT — Ürün Ekleme Formu
📌 Hedef
UrunEkleFormu.cs ile veritabanına yeni ürün eklemek.
🎨 Form Tasarımı
Kontrol Name Text/Özellik
Label — Ürün Adı:
TextBox txtUrunAdi —
Label — Barkod:
TextBox txtBarkod —
Label — Fiyat:
TextBox txtFiyat —
Label — Stok Miktarı:
TextBox txtStokMiktari —
Label — Kategori:
ComboBox cmbKategori DropDownStyle: DropDownList
Button btnKaydet 💾 Kaydet
Button btnTemizle 🗑️ Temizle
Button btnIptal ✖️ İptal
💻 UrunEkleFormu.cs — Tam Kod
csharp
using System;
using System.Windows.Forms;
using Microsoft.Data.SqlClient;
using StokYonetimi.Helpers;
namespace StokYonetimi.Forms
{
public partial class UrunEkleFormu : Form
{
public UrunEkleFormu()
{
InitializeComponent();
}
// Form açılırken kategorileri yükle
private void UrunEkleFormu_Load(object sender, EventArgs e)
{
KategorileriYukle();
}
private void KategorileriYukle()
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = “SELECT KategoriID, KategoriAdi FROM Kategoriler ORDER BY KategoriAdi”;
using (var cmd = new SqlCommand(sql, conn))
using (var reader = cmd.ExecuteReader())
{
cmbKategori.Items.Clear();
while (reader.Read())
{
cmbKategori.Items.Add(new
{
ID = reader.GetInt32(0),
Ad = reader.GetString(1)
});
}
}
}
cmbKategori.DisplayMember = “Ad”;
cmbKategori.ValueMember = “ID”;
}
catch (Exception ex)
{
MessageBox.Show(“Kategori yükleme hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Kaydet butonu
private void btnKaydet_Click(object sender, EventArgs e)
{
// —– Validasyon —–
if (string.IsNullOrWhiteSpace(txtUrunAdi.Text))
{
MessageBox.Show(“Ürün adı boş olamaz!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtUrunAdi.Focus();
return;
}
if (!decimal.TryParse(txtFiyat.Text, out decimal fiyat) || fiyat < 0)
{
MessageBox.Show(“Geçerli bir fiyat girin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtFiyat.Focus();
return;
}
if (!int.TryParse(txtStokMiktari.Text, out int stok) || stok < 0)
{
MessageBox.Show(“Geçerli bir stok miktarı girin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtStokMiktari.Focus();
return;
}
if (cmbKategori.SelectedItem == null)
{
MessageBox.Show(“Lütfen bir kategori seçin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// —– Veritabanına Kaydet —–
try
{
// Seçilen kategorinin ID’sini al
dynamic seciliKategori = cmbKategori.SelectedItem;
int kategoriId = seciliKategori.ID;
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = @”INSERT INTO Urunler
(UrunAdi, Barkod, Fiyat, StokMiktari, KategoriID)
VALUES
(@UrunAdi, @Barkod, @Fiyat, @StokMiktari, @KategoriID)”;
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue(“@UrunAdi”, txtUrunAdi.Text.Trim());
cmd.Parameters.AddWithValue(“@Barkod”, string.IsNullOrWhiteSpace(txtBarkod.Text)
? DBNull.Value
: (object)txtBarkod.Text.Trim());
cmd.Parameters.AddWithValue(“@Fiyat”, fiyat);
cmd.Parameters.AddWithValue(“@StokMiktari”, stok);
cmd.Parameters.AddWithValue(“@KategoriID”, kategoriId);
cmd.ExecuteNonQuery();
}
}
MessageBox.Show(“✅ Ürün başarıyla eklendi!”, “Başarılı”,
MessageBoxButtons.OK, MessageBoxIcon.Information);
FormTemizle();
}
catch (SqlException ex) when (ex.Number == 2627) // Unique constraint (Barkod)
{
MessageBox.Show(“Bu barkod zaten kayıtlı! Farklı bir barkod girin.”, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(“Kayıt hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Temizle butonu
private void btnTemizle_Click(object sender, EventArgs e)
{
FormTemizle();
}
private void FormTemizle()
{
txtUrunAdi.Clear();
txtBarkod.Clear();
txtFiyat.Clear();
txtStokMiktari.Clear();
cmbKategori.SelectedIndex = -1;
txtUrunAdi.Focus();
}
// İptal butonu
private void btnIptal_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
✅ Saat 3 Kontrol Listesi
UrunEkleFormu tasarlandı
Kategoriler ComboBox’a yükleniyor
Validasyonlar çalışıyor
Ürün veritabanına kaydediliyor
Barkod çakışması hatası yakalanıyor
⏱️ 4. SAAT — Ürünleri Listeleme & Silme
📌 Hedef
UrunListeFormu.cs ile tüm ürünleri listelemek ve seçilen ürünü silmek.
🎨 Form Tasarımı
Kontrol Name Özellik
TextBox txtArama PlaceholderText: “🔍 Ürün adı veya barkod ara…”
Button btnAra 🔍 Ara
Button btnTumunuGoster 📋 Tümünü Göster
DataGridView dgvUrunler FullRowSelect, ReadOnly
Button btnSil 🗑️ Seçileni Sil
Button btnDuzenle ✏️ Düzenle
Label lblToplamKayit —
💻 UrunListeFormu.cs — Tam Kod
csharp
using System;
using System.Data;
using System.Windows.Forms;
using Microsoft.Data.SqlClient;
using StokYonetimi.Helpers;
namespace StokYonetimi.Forms
{
public partial class UrunListeFormu : Form
{
public UrunListeFormu()
{
InitializeComponent();
}
private void UrunListeFormu_Load(object sender, EventArgs e)
{
DataGridViewAyarla();
UrunleriYukle();
}
// DataGridView görsel ayarları
private void DataGridViewAyarla()
{
dgvUrunler.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgvUrunler.MultiSelect = false;
dgvUrunler.ReadOnly = true;
dgvUrunler.AllowUserToAddRows = false;
dgvUrunler.AllowUserToDeleteRows = false;
dgvUrunler.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
}
// Tüm ürünleri yükle
private void UrunleriYukle(string aramaMetni = “”)
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = @”
SELECT
u.UrunID AS [ID],
u.UrunAdi AS [Ürün Adı],
u.Barkod AS [Barkod],
k.KategoriAdi AS [Kategori],
u.Fiyat AS [Fiyat (₺)],
u.StokMiktari AS [Stok],
u.EklenmeTarihi AS [Eklenme Tarihi]
FROM Urunler u
JOIN Kategoriler k ON u.KategoriID = k.KategoriID
WHERE u.UrunAdi LIKE @Arama OR u.Barkod LIKE @Arama
ORDER BY u.UrunAdi”;
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue(“@Arama”, “%” + aramaMetni + “%”);
var adapter = new SqlDataAdapter(cmd);
var tablo = new DataTable();
adapter.Fill(tablo);
dgvUrunler.DataSource = tablo;
lblToplamKayit.Text = $”Toplam: {tablo.Rows.Count} kayıt”;
}
}
}
catch (Exception ex)
{
MessageBox.Show(“Veri yükleme hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Ara butonu
private void btnAra_Click(object sender, EventArgs e)
{
UrunleriYukle(txtArama.Text.Trim());
}
// Tümünü Göster butonu
private void btnTumunuGoster_Click(object sender, EventArgs e)
{
txtArama.Clear();
UrunleriYukle();
}
// Enter tuşuyla arama
private void txtArama_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
UrunleriYukle(txtArama.Text.Trim());
}
// Sil butonu
private void btnSil_Click(object sender, EventArgs e)
{
if (dgvUrunler.SelectedRows.Count == 0)
{
MessageBox.Show(“Lütfen silmek istediğiniz ürünü seçin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Seçilen satırdan ID ve adı al
var seciliSatir = dgvUrunler.SelectedRows[0];
int urunId = Convert.ToInt32(seciliSatir.Cells[“ID”].Value);
string urunAdi = seciliSatir.Cells[“Ürün Adı”].Value.ToString();
// Onay sor
var sonuc = MessageBox.Show(
$”‘{urunAdi}’ ürününü silmek istediğinizden emin misiniz?”,
“Silme Onayı”,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (sonuc != DialogResult.Yes) return;
// Veritabanından sil
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = “DELETE FROM Urunler WHERE UrunID = @UrunID”;
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue(“@UrunID”, urunId);
cmd.ExecuteNonQuery();
}
}
MessageBox.Show(“✅ Ürün başarıyla silindi!”, “Başarılı”,
MessageBoxButtons.OK, MessageBoxIcon.Information);
UrunleriYukle(); // Listeyi yenile
}
catch (Exception ex)
{
MessageBox.Show(“Silme hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Düzenle butonu
private void btnDuzenle_Click(object sender, EventArgs e)
{
if (dgvUrunler.SelectedRows.Count == 0)
{
MessageBox.Show(“Lütfen düzenlemek istediğiniz ürünü seçin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
int urunId = Convert.ToInt32(dgvUrunler.SelectedRows[0].Cells[“ID”].Value);
var guncelleFormu = new UrunGuncelleFormu(urunId);
guncelleFormu.ShowDialog();
UrunleriYukle(); // Güncelleme sonrası listeyi yenile
}
}
}
✅ Saat 4 Kontrol Listesi
DataGridView ürünleri listeliyor
Arama kutusu çalışıyor
Enter tuşuyla arama yapılıyor
Silme onay penceresi çıkıyor
Silme sonrası liste yenileniyor
⏱️ 5. SAAT — Ürün Güncelleme
📌 Hedef
Seçilen ürünün bilgilerini düzenleyip veritabanını güncellemek.
🎨 Form Tasarımı
UrunEkleFormu ile aynı kontroller — sadece başlık ve buton metni farklı.
Kontrol Name Açıklama
TextBox txtUrunAdi —
TextBox txtBarkod —
TextBox txtFiyat —
TextBox txtStokMiktari —
ComboBox cmbKategori —
Button btnGuncelle 💾 Güncelle
Button btnIptal ✖️ İptal
💻 UrunGuncelleFormu.cs — Tam Kod
csharp
using System;
using System.Windows.Forms;
using Microsoft.Data.SqlClient;
using StokYonetimi.Helpers;
namespace StokYonetimi.Forms
{
public partial class UrunGuncelleFormu : Form
{
private readonly int _urunId;
// Constructor: güncellenecek ürünün ID’si parametre olarak gelir
public UrunGuncelleFormu(int urunId)
{
InitializeComponent();
_urunId = urunId;
}
private void UrunGuncelleFormu_Load(object sender, EventArgs e)
{
KategorileriYukle();
UrunBilgileriniGetir();
}
private void KategorileriYukle()
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = “SELECT KategoriID, KategoriAdi FROM Kategoriler ORDER BY KategoriAdi”;
using (var cmd = new SqlCommand(sql, conn))
using (var reader = cmd.ExecuteReader())
{
cmbKategori.Items.Clear();
while (reader.Read())
{
cmbKategori.Items.Add(new
{
ID = reader.GetInt32(0),
Ad = reader.GetString(1)
});
}
}
}
cmbKategori.DisplayMember = “Ad”;
cmbKategori.ValueMember = “ID”;
}
catch (Exception ex)
{
MessageBox.Show(“Kategori yükleme hatası: ” + ex.Message);
}
}
// Mevcut ürün bilgilerini forma getir
private void UrunBilgileriniGetir()
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = @”SELECT UrunAdi, Barkod, Fiyat, StokMiktari, KategoriID
FROM Urunler WHERE UrunID = @UrunID”;
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue(“@UrunID”, _urunId);
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
txtUrunAdi.Text = reader[“UrunAdi”].ToString();
txtBarkod.Text = reader[“Barkod”] == DBNull.Value
? “” : reader[“Barkod”].ToString();
txtFiyat.Text = reader[“Fiyat”].ToString();
txtStokMiktari.Text = reader[“StokMiktari”].ToString();
// Kategoriye ait ComboBox öğesini seç
int kategoriId = Convert.ToInt32(reader[“KategoriID”]);
for (int i = 0; i < cmbKategori.Items.Count; i++)
{
dynamic item = cmbKategori.Items[i];
if (item.ID == kategoriId)
{
cmbKategori.SelectedIndex = i;
break;
}
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(“Veri getirme hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Güncelle butonu
private void btnGuncelle_Click(object sender, EventArgs e)
{
// —– Validasyon —–
if (string.IsNullOrWhiteSpace(txtUrunAdi.Text))
{
MessageBox.Show(“Ürün adı boş olamaz!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (!decimal.TryParse(txtFiyat.Text, out decimal fiyat) || fiyat < 0)
{
MessageBox.Show(“Geçerli bir fiyat girin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (!int.TryParse(txtStokMiktari.Text, out int stok) || stok < 0)
{
MessageBox.Show(“Geçerli bir stok miktarı girin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (cmbKategori.SelectedItem == null)
{
MessageBox.Show(“Lütfen bir kategori seçin!”, “Uyarı”,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// —– Veritabanını Güncelle —–
try
{
dynamic seciliKategori = cmbKategori.SelectedItem;
int kategoriId = seciliKategori.ID;
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = @”UPDATE Urunler SET
UrunAdi = @UrunAdi,
Barkod = @Barkod,
Fiyat = @Fiyat,
StokMiktari = @StokMiktari,
KategoriID = @KategoriID
WHERE UrunID = @UrunID”;
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue(“@UrunAdi”, txtUrunAdi.Text.Trim());
cmd.Parameters.AddWithValue(“@Barkod”, string.IsNullOrWhiteSpace(txtBarkod.Text)
? DBNull.Value
: (object)txtBarkod.Text.Trim());
cmd.Parameters.AddWithValue(“@Fiyat”, fiyat);
cmd.Parameters.AddWithValue(“@StokMiktari”, stok);
cmd.Parameters.AddWithValue(“@KategoriID”, kategoriId);
cmd.Parameters.AddWithValue(“@UrunID”, _urunId);
cmd.ExecuteNonQuery();
}
}
MessageBox.Show(“✅ Ürün başarıyla güncellendi!”, “Başarılı”,
MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
catch (SqlException ex) when (ex.Number == 2627)
{
MessageBox.Show(“Bu barkod zaten kayıtlı!”, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(“Güncelleme hatası: ” + ex.Message, “Hata”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// İptal butonu
private void btnIptal_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
✅ Saat 5 Kontrol Listesi
Güncelleme formu açılıyor
Mevcut ürün bilgileri forma geliyor
Kategori doğru seçili geliyor
Güncelleme veritabanına yansıyor
Liste otomatik yenileniyor
⏱️ 6. SAAT — Son Dokunuşlar & Test
📌 Hedef
Stok durumuna göre renklendirme, kategori bazlı filtreleme, genel test.
🎨 Özellik 1 — Stok Uyarısı (Kırmızı Renk)
UrunListeFormu.cs’e ekleyin — DataGridView’in CellFormatting olayına:
csharp
private void dgvUrunler_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex < 0) return;
var satir = dgvUrunler.Rows[e.RowIndex];
var stokHucresi = satir.Cells[“Stok”];
if (stokHucresi.Value != null && int.TryParse(stokHucresi.Value.ToString(), out int stok))
{
if (stok == 0)
{
// Stok yok → kırmızı
satir.DefaultCellStyle.BackColor = Color.FromArgb(255, 200, 200);
satir.DefaultCellStyle.ForeColor = Color.DarkRed;
}
else if (stok < 5)
{
// Stok az → sarı
satir.DefaultCellStyle.BackColor = Color.FromArgb(255, 255, 180);
satir.DefaultCellStyle.ForeColor = Color.DarkOliveGreen;
}
else
{
satir.DefaultCellStyle.BackColor = Color.White;
satir.DefaultCellStyle.ForeColor = Color.Black;
}
}
}
📊 Özellik 2 — Stok Özet Raporu
Ana sayfaya veya liste formuna ekleyebilirsiniz:
csharp
private void StokRaporuGoster()
{
try
{
using (var conn = DbHelper.GetConnection())
{
conn.Open();
string sql = @”
SELECT
COUNT(*) AS ToplamUrun,
SUM(StokMiktari) AS ToplamStok,
COUNT(CASE WHEN StokMiktari = 0 THEN 1 END) AS TukenenUrun,
COUNT(CASE WHEN StokMiktari < 5 AND StokMiktari > 0 THEN 1 END) AS KritikStok
FROM Urunler”;
using (var cmd = new SqlCommand(sql, conn))
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
lblToplamUrun.Text = $”Toplam Ürün: {reader[“ToplamUrun”]}”;
lblToplamStok.Text = $”Toplam Stok: {reader[“ToplamStok”]}”;
lblTukenenUrun.Text = $”Tükenen: {reader[“TukenenUrun”]}”;
lblKritikStok.Text = $”Kritik Stok: {reader[“KritikStok”]}”;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(“Rapor hatası: ” + ex.Message);
}
}
🧪 Final Test Senaryoları
# Test Adımı Beklenen Sonuç
1 Uygulama başlat DB bağlantısı başarılı
2 Yeni ürün ekle (boş ad ile) “Ürün adı boş olamaz!” uyarısı
3 Aynı barkodla 2. ürün ekle “Barkod zaten kayıtlı!” hatası
4 Geçersiz fiyat gir (harf) “Geçerli bir fiyat girin!” uyarısı
5 Ürün ekle (geçerli verilerle) “Başarıyla eklendi!” mesajı
6 Listede ürünü arayla Sadece eşleşenler gelsin
7 Ürünü düzenle & kaydet Listede değişsin
8 Ürünü sil (Evet ile) Listeden kalksın
9 Ürünü sil (Hayır ile) Silinmesin
10 Stok=0 olan ürün Kırmızı renk gösterin
✅ Saat 6 Kontrol Listesi
Stok renklendirme çalışıyor (kırmızı/sarı/beyaz)
Stok raporu doğru sayıları gösteriyor
Tüm test senaryoları geçti
Uygulama hatasız çalışıyor
📁 SQL Script — Hızlı Referans
sql
— Tüm ürünleri listele
SELECT u.*, k.KategoriAdi FROM Urunler u JOIN Kategoriler k ON u.KategoriID = k.KategoriID;
— Tükenen ürünler
SELECT * FROM Urunler WHERE StokMiktari = 0;
— Kritik stok (5’ten az)
SELECT * FROM Urunler WHERE StokMiktari > 0 AND StokMiktari < 5;
— Kategoriye göre ürün sayısı
SELECT k.KategoriAdi, COUNT(u.UrunID) AS UrunSayisi
FROM Kategoriler k LEFT JOIN Urunler u ON k.KategoriID = u.KategoriID
GROUP BY k.KategoriAdi;
— En pahalı 5 ürün
SELECT TOP 5 UrunAdi, Fiyat FROM Urunler ORDER BY Fiyat DESC;
🚨 Sık Yapılan Hatalar & Çözümleri
Hata Sebep Çözüm
Cannot open server Sunucu adı yanlış Connection string’de server adını kontrol et
Login failed Windows auth çalışmıyor Trusted_Connection=True ekle
SSL connection error Sertifika sorunu TrustServerCertificate=True ekle
Object reference null ComboBox seçilmedi SelectedItem == null kontrolü ekle
Input string not in correct format TryParse kullanılmadı decimal.TryParse ile kontrol et
Duplicate key error Aynı barkod SqlException.Number == 2627 yakala