Parameterized query with dynamic where clasue
-
13-06-2021 - |
题
So I have this query:
var comm = @"SELECT * FROM `TABLE` ";
bool hasWhere = false;
if ( model.Serial > 0 ) {
comm += " WHERE `SERIAL` LIKE '%" + model.Serial + "%' ";
hasWhere = true;
}
if ( model.Id.HasValue && model.Id.Value > 0 ) {
if ( !hasWhere ) {
comm += " WHERE `NUIP` LIKE '%" + model.Id.Value + "%' ";
hasWhere = true;
} else
comm += " AND `NUIP` LIKE '%" + model.Id.Value + "%' ";
}
if ( model.Date.HasValue ) {
if ( !hasWhere ) {
comm += " WHERE `DATE` = '" + model.Date.Value + "' ";
hasWhere = true;
} else
comm += " AND `DATE` = '" + model.Date.Value + "' ";
}
....
....
....
I've read about parameterized queries against SQL Injection and so on. The thing is, given that I'll have a dynamic number of WHERE clauses (based on the search model),how can I parameterize the query? I can't put WHERE a = @A AND b=@B...
because the user must not need to search based on all the columns.
Any idea? thanks in advance.
P.S: Can't use LINQ or something similar to that (-business rules-).
解决方案
You can still use SQL parameterized query with where close (WHERE will be sort of dynamic). For example I have paramater @SerialNum that is NULL and I have a parameter @Code that equals to 455.
SELECT
Column1
,Column2
FROM
YourTable
WHERE
(
@SerialNum IS NULL
OR
Column3 LIKE '%' + @SerialNum + '%'
)
AND
(
@Code IS NULL
OR
Column4 LIKE '%' + @Code + '%'
)
其他提示
I use this trick.
....
WHERE 1 = 1
AND a = a
AND b= @b
AND c = c
... etc....
ie I compare the column to it self if I don't want to search
var comm = @"SELECT * FROM `TABLE` WHERE 1 = 1 ";
if ( model.Serial > 0 ) {
comm += " AND `SERIAL` LIKE '%" + model.Serial + "%' ";
} else {
comm += " AND `SERIAL` = `SERIAL`";
}
if ( model.Id.HasValue && model.Id.Value > 0 ) {
comm += " AND `AND` LIKE '%" + model.Id.Value + "%' ";
} else {
comm += " AND `NUIP` = `NUIP` ";
}
....
WHERE 1 = 1
is optimised away and removes the need to remember if a WHERE is defined yet or not, and all the searches are either optimised away (AND a=a
) or have search applied (AND a = xxx
).
You just add a single if
for each search!
Also I'd use a StringBuilder to clean up the string handling.