最近在做乙個動態拼接where條件的查詢,大概想到了以下幾種方法:
1、**內拼接查詢條件,sql也是寫在**內的。
2、**內拼接查詢條件,sql寫在儲存過程內,將 where條件作為乙個字串傳入儲存過程。(這種需要在**內過濾sql注入的問題)
3、查詢條件的拼接放到儲存過程內,在儲存過程內對查詢條件值進行引數化。
第一種:
不再書寫
第二種:
第1步,先拼接where查詢條件
stringbuilder condition = newstringbuilder();
if (param.province > 0
)
", param.province);
}if (param.city > 0
)
", param.city);
}if (param.county > 0
)
", param.county);
}
第2步:
注意,condition引數,將拼接的查詢條件作為字串傳入,
dynamicparameters parameters = newdynamicparameters();
parameters.add(
"condition
", condition.tostring());
第3步:
接下來看下儲存過程。只看下關鍵的地方,將拼接好的where條件作為乙個字串傳入儲存過程,這種應該還是有sql注入的問題,因為第一步拼接的時候並沒有對引數值進行引數化
set@sql='
select @totalcount = count(1)
from dbo.base_class cls
where isvalid=1 '+
@condition
;
第三種:
第1步:將所有用到的查詢引數傳給儲存過程
var parameters = newdynamicparameters();
parameters.add(
"province
", param.province);
parameters.add(
"city
", param.city);
parameters.add(
"county
", param.county);
第2步:儲存過程內拼接,並引數化(**只留了關鍵部分,並不能保證編譯通過)
procedure[dbo
].[p_getlist
]@p_province
int,
@p_city
int,
@p_county
int,
asbegin
declare
@sql
nvarchar(max
) ,@sqlcondition
nvarchar(max
) ,
@parm
nvarchar(max
) ,set
@sql=''
;
set@sqlcondition=''
;
set@parm=''
;if(@p_province
>0)
begin
set@sqlcondition+='
and province=@p_province
'end
set@parm+='
@p_province int,';
if(@p_city
>0)
begin
set@sqlcondition+='
and city=@p_city
'end
set@parm+='
@p_city int,';
if(@p_county
>0)
begin
set@sqlcondition+='
and county=@p_county
'end
set@parm+='
@p_county int,';
--這個引數展示了,怎麼拼接like這樣的查詢條件
if(@p_schoolname
isnot
null
)
begin
set@sqlcondition+='
and name like ''%
''+@p_schoolname+''%
'''end
set@parm+='
@p_schoolname nvarchar(100),';
if (@parm
<>'')
begin
set@parm
=substring(@parm,1,len(@parm)-1)
endset
@sql='
select count(1)
from tablename
where isvalid=1 '+
@sqlcondition
;
set@sql='
select
*from tablename
where isvalid=1 '+
@sqlcondition;
exec sp_executesql @sql,@parm
,@p_province
=@p_province
,
@p_city
=@p_city
,
@p_county
=@p_county
end
有個地方需要注意,使用 sp_executesql 時, 第二個引數@pram的拼接並不是和 查詢條件同時進行的,查詢條件只有輸入值時才拼接,而@pram 將所有的查詢條件中的引數拼接。如果查詢條件中沒有用到某個引數,但在sp_executesql 的輸入引數中過多的指定引數,也是可以的。這樣就解決了 查詢條件引數個數不固定的情況下,無法解決給 sp_executesql 輸入引數賦值的問題,因為不知道要給多少個引數賦值。
一開始也是這麼做的,但可能因為其他錯誤導致報「過多的指定引數」的錯誤,以為這種方式不可以,最終還是通過了。
第一種的弊端也顯而易見,改一次結構就要修改**,第二種可讀性一般但需要解決注入的問題,第三種可讀性較差但好像又找不出毛病。不知道有沒有其他更好的方式解決這種需要拼接sql才能處理不固定查詢條件的方法。
寫完了,要去刷牙吃早飯咯。
JPA動態拼接where條件
在開發中,經常會涉及到動態拼接sql,以下就是jpa拼接條件案例 兩種方法大同小異,只不過語法方面不同 mysql 使用三元運算子的方式 query value select from user a where if 1 id 1 1 1 nativequery true public listfi...
多where條件查詢
create tabletb 工廠 varchar 10 庫地 int,型別 varchar 10 屬性 varchar 10 sku varchar 10 批次 varchar 10 名稱 varchar 10 入庫時間 datetime 數量 int,重量 int 備註 varchar 10 i...
關於where的條件查詢in
表示式查詢 map 欄位1 array 表示式 查詢條件1 map 欄位2 array 表示式 查詢條件2 model where map select 也支援 表示式不分大小寫,支援的查詢表示式有下面幾種,分別表示的含義是 表示式含義 eq等於 neq不等於 gt大於 egt大於等於 lt小於 e...