Để kết nối WinForms (Windows Forms Application) với SQL Server, bạn thực hiện theo các bước dưới đây
WinForms dùng ADO.NET để kết nối, cần System.Data.SqlClient:
using System.Data;
using System.Data.SqlClient;
Dạng cơ bản:
string connectionString = "Server=TEN_SERVER;Database=TEN_CSDL;User Id=USERNAME;Password=MATKHAU;";
Ví dụ sử dụng SQL Server Authentication:
string connectionString = "Server=localhost;Database=QLSV;User Id=sa;Password=123;";
Ví dụ dùng Windows Authentication:
string connectionString = "Server=localhost;Database=QLSV;Integrated Security=True;";
Ví dụ: Kết nối và đọc dữ liệu từ bảng SinhVien
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace DemoConnectSQL
{
public partial class Form1 : Form
{
string connectionString = "Server=localhost;Database=QLSV;Integrated Security=True;";
public Form1()
{
InitializeComponent();
}
private void btnLoad_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
try
{
conn.Open();
string sql = "SELECT * FROM SinhVien";
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show("Lỗi kết nối: " + ex.Message);
}
}
}
}
}
Đảm bảo SQL Server đang chạy.
Tên server có thể là:
localhost: . (chấm)
MAYTINH\SQLEXPRESS (nếu bạn cài bản SQL Server Express)
Nên kiểm tra SQL bằng SQL Server Management Studio trước.
Để làm phần mềm thương mại, hay nhiều thành viên làm phần mềm winform cần chú ý các vấn đề sau.
Khi bạn dùng kết nối với SQL Server (hoặc thao tác với bất kỳ tài nguyên nào như file, stream, v.v...), bạn nên sử dụng using để đảm bảo tự động giải phóng tài nguyên sau khi dùng xong.
✅ Lý do dùng using
Các đối tượng như SqlConnection, SqlCommand, SqlDataReader là các đối tượng quản lý tài nguyên hệ thống (mạng, bộ nhớ, handle...). Nếu bạn không giải phóng, ứng dụng dễ bị rò rỉ bộ nhớ hoặc khóa tài nguyên.
using giúp đảm bảo gọi Dispose() tự động, dù có lỗi xảy ra hay không.
📌 Cú pháp using
using (var obj = new SomeDisposableObject())
{
// code sử dụng obj
} // -> tự động gọi obj.Dispose() khi ra khỏi khối
✅ Ví dụ thực tế: Không dùng using ❌
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM SinhVien", conn);
SqlDataReader reader = cmd.ExecuteReader();
// Xử lý dữ liệu...
reader.Close();
conn.Close();
➡️ Nhược điểm: Nếu xảy ra lỗi trước khi gọi Close(), tài nguyên sẽ không được giải phóng.
✅ Dùng using ✔️
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT * FROM SinhVien", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string ten = reader["TenSV"].ToString();
// xử lý...
}
}
}
}
➡️ Ưu điểm:
Dù có lỗi xảy ra, các đối tượng vẫn được tự động đóng và giải phóng.
Code gọn gàng, rõ ràng.
✅ Khi nào using có tác dụng?
Khi đối tượng implement IDisposable, ví dụ:
SqlConnection
SqlCommand
SqlDataReader
FileStream
StreamReader
MemoryStream
✅ Gợi ý nâng cao
Bạn có thể lồng nhiều using hoặc gộp chung:
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM SV", conn))
{
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// xử lý
}
}
Đây là một kỹ thuật rất quan trọng để bảo mật ứng dụng khi kết nối với SQL Server:
✅ Sử dụng SqlParameter để tránh SQL Injection
❗ Vấn đề: SQL Injection là gì?
SQL Injection là một lỗ hổng bảo mật nghiêm trọng cho phép kẻ tấn công chèn mã SQL độc hại vào câu lệnh truy vấn thông qua input người dùng.
❌ Ví dụ nguy hiểm:
string user = txtUser.Text;
string pass = txtPass.Text;
string sql = "SELECT * FROM TaiKhoan WHERE UserName = '" + user + "' AND Password = '" + pass + "'";
Nếu người dùng nhập:
User: admin
Pass: ' OR '1'='1
Thì câu SQL sẽ thành:
SELECT * FROM TaiKhoan WHERE UserName = 'admin' AND Password = '' OR '1'='1'
➡️ Kết quả: Đăng nhập thành công không cần mật khẩu ❌
✅ Giải pháp: Dùng SqlParameter
🔐 Cách an toàn để không bị hack:
string user = txtUser.Text;
string pass = txtPass.Text;
string sql = "SELECT * FROM TaiKhoan WHERE UserName = @user AND Password = @pass";
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@user", user);
cmd.Parameters.AddWithValue("@pass", pass);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
MessageBox.Show("Đăng nhập thành công");
}
else
{
MessageBox.Show("Sai tài khoản hoặc mật khẩu");
}
}
✅ Giải thích:
@user, @pass: là tên tham số trong câu lệnh SQL.
cmd.Parameters.AddWithValue(...): gán giá trị input một cách an toàn.
SqlParameter sẽ tự động:
Escape ký tự nguy hiểm (', --, ;, ...)
Chống injection
Tự kiểm tra kiểu dữ liệu
📌 Có thể viết rõ kiểu hơn:
cmd.Parameters.Add(new SqlParameter("@user", SqlDbType.VarChar) { Value = user });
✅ Ưu điểm:
Ưu điểm Lý do
An toàn Tránh được SQL Injection
Tối ưu hóa hiệu suất SQL Server cache câu lệnh có tham số dễ hơn
Rõ ràng, dễ bảo trì Không cần nối chuỗi phức tạp
✅ Một ví dụ khác: Insert dữ liệu
string sql = "INSERT INTO SinhVien (MaSV, TenSV, Lop) VALUES (@ma, @ten, @lop)";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@ma", txtMa.Text);
cmd.Parameters.AddWithValue("@ten", txtTen.Text);
cmd.Parameters.AddWithValue("@lop", cboLop.Text);
cmd.ExecuteNonQuery();
}
Việc tạo một lớp DBHelper giúp bạn:
✅ Tái sử dụng kết nối và xử lý SQL
✅ Code gọn gàng, dễ bảo trì
✅ Tách riêng phần truy cập dữ liệu khỏi giao diện WinForms
✅ Mục tiêu của DBHelper:
Mở kết nối
Thực thi lệnh SELECT, INSERT, UPDATE, DELETE
Hỗ trợ SqlParameter
Dùng using để tự động giải phóng
✅Tạo lớp DBHelper.cs
using System;
using System.Data;
using System.Data.SqlClient;
public static class DBHelper
{
private static string connectionString = "Server=localhost;Database=QLSV;Integrated Security=True;";
// Hàm SELECT, trả về DataTable
public static DataTable GetData(string sql, params SqlParameter[] parameters)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
dt.Load(reader);
}
}
return dt;
}
// Hàm thực thi INSERT, UPDATE, DELETE (trả về số dòng ảnh hưởng)
public static int Execute(string sql, params SqlParameter[] parameters)
{
int affectedRows = 0;
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters);
conn.Open();
affectedRows = cmd.ExecuteNonQuery();
}
return affectedRows;
}
// Hàm lấy một giá trị đơn (ví dụ SELECT COUNT(*) hoặc MAX...)
public static object GetScalar(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
if (parameters != null)
cmd.Parameters.AddRange(parameters);
conn.Open();
return cmd.ExecuteScalar();
}
}
}
✅ Cách sử dụng lớp DBHelper
📌 Ví dụ 1: Load dữ liệu vào DataGridView
string sql = "SELECT * FROM SinhVien WHERE Lop = @lop";
var dt = DBHelper.GetData(sql, new SqlParameter("@lop", "12A1"));
dataGridView1.DataSource = dt;
📌 Ví dụ 2: Thêm sinh viên
string sql = "INSERT INTO SinhVien (MaSV, TenSV, Lop) VALUES (@ma, @ten, @lop)";
int result = DBHelper.Execute(sql,
new SqlParameter("@ma", txtMa.Text),
new SqlParameter("@ten", txtTen.Text),
new SqlParameter("@lop", cboLop.Text)
);
MessageBox.Show(result > 0 ? "Thêm thành công" : "Thêm thất bại");
📌 Ví dụ 3: Lấy tổng số sinh viên
string sql = "SELECT COUNT(*) FROM SinhVien";
int total = Convert.ToInt32(DBHelper.GetScalar(sql));
lblTong.Text = "Tổng SV: " + total;
Tìm kiếm:
Hướng dẫn thực hành kết nối từ A-Z kết nối Winform với SQL Server, có bài tập, video thực hành trong khóa học winform từ cơ bản đến nâng cao.