最近在項目上遇到幾個問題,關于ADO.NET中SQL綁定變量
總結一下,分享給大家。
1. 使用 SqlParameter
(推薦方式,防止 SQL 注入)
ADO.NET 提供 SqlParameter
來綁定變量,從而提高安全性和性能。
- 防止 SQL 注入攻擊。
- 支持各種數據類型,避免 SQL 解析器重新編譯。
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = "your_connection_string";
string query = "SELECT * FROM Users WHERE Username = @Username";
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.Add(new SqlParameter("@Username", SqlDbType.NVarChar) { Value = "test_user" });
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader["Username"]);
}
}
}
}
}
2. 使用 AddWithValue
方法
如果不需要顯式指定參數類型,可以用 AddWithValue
直接傳值:
cmd.Parameters.AddWithValue("@Username", "test_user");
需要注意以下2個問題:
AddWithValue
可能導致隱式轉換,影響性能(比如 int
傳 nvarchar
)。- 適用于簡單情況,但不推薦用于復雜查詢。
3. 存儲過程(Stored Procedure)+ 綁定變量
綁定變量也可以用于存儲過程,提高安全性和代碼復用性。
- 提高 SQL 復用性和執行效率(緩存執行計劃)。
- 更安全,避免 SQL 注入。
SQL Server 端(創建存儲過程):
CREATE PROCEDURE GetUserByUsername
@Username NVARCHAR(50)
AS
BEGIN
SELECT * FROM Users WHERE Username = @Username
END
C#調用代碼
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetUserByUsername";
cmd.Parameters.Add(new SqlParameter("@Username", SqlDbType.NVarChar) { Value = "test_user" });
4. 批量綁定變量(Table-Valued Parameter,TVP)
如果需要傳遞多個值給 SQL 查詢,可以使用 TVP 綁定變量,提高批量操作的性能。
- 適用于批量查詢或批量插入,提高性能。
- 避免循環執行 SQL 語句的開銷。
SQL Server 端(創建 TVP 類型):
CREATE TYPE UserTableType AS TABLE
(
UserId INT
)
C# 代碼(傳遞多個 UserId):
DataTable userTable = new DataTable();
userTable.Columns.Add("UserId", typeof(int));
userTable.Rows.Add(1);
userTable.Rows.Add(2);
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE UserId IN (SELECT UserId FROM @UserTable)", conn))
{
cmd.Parameters.Add(new SqlParameter("@UserTable", SqlDbType.Structured) { TypeName = "UserTableType", Value = userTable });
}
以上是C# ADO.NET 綁定變量的幾種常見模式和示例代碼。
轉自https://www.cnblogs.com/tianqing/p/18774515
該文章在 2025/3/17 9:27:33 編輯過