ALTER PROCEDURE [dbo].[proc_test] ( @orderby nvarchar(100) = ' order by id desc ', @userid int, @stime datetime, @etime datetime ) AS BEGIN DECLARE @strWhere nvarchar(1000)=''; --where條件 DECLARE @execsql nvarchar(1000); -- 主語句 DECLARE @param nvarchar(1000); -- 參數 -------拼接where條件--------------------------------------------------------------------- if(@userid>0) begin SET @strWhere += ' and [userid] = @userid ' end --'1753/1/1 0:00:00'為時間傳過來的默認值,表示無此篩選條件 if(@stime <> '' and @stime>'1753/1/1 0:00:00') begin SET @strWhere += ' and [time] >= @stime ' end --'1753/1/1 0:00:00'為時間傳過來的默認值,表示無此篩選條件 if(@etime <> '' and @etime>'1753/1/1 0:00:00') begin SET @strWhere += ' and [time] <= @etime ' end ------拼接where條件 end--------------------------------------------------------------------- --查詢sql set @execsql = ' SELECT TOP 1000 [id] ,[time] FROM [tradeinfo] WHERE 1 = 1 ' + @strWhere +@orderby; --參數化處理 set @param =N'@userid int,@stime datetime,@etime datetime'; EXEC sys.sp_executesql @execsql ,@param, @userid=@userid, @stime =@stime, @etime =@etime END
c#調用如下:
SqlParameter[] parameters = { new SqlParameter("@orderby", SqlDbType.VarChar, 30), new SqlParameter("@userid", SqlDbType.Int,4), new SqlParameter("@stime", SqlDbType.DateTime,9), new SqlParameter("@etime", SqlDbType.DateTime,9) }; parameters[0].Value = " order by id desc "; parameters[1].Value = 0; parameters[2].Value = SqlDateTime.MinValue.Value;//默認最小值:1753/1/1 0:00:00 parameters[3].Value = SqlDateTime.MinValue.Value;//默認最小值:1753/1/1 0:00:00 var ds = ExecuteNonQuery(CommandType.StoredProcedure, "proc_test", parameters);
上面的存儲過程做了參數化處理,可以避免sql注入,相比直接拼接(SET @strWhere += ' and [userid] = ' +convert(varchar,@userid),然后用EXEC()方法執行),更高效、更安全,當然維護起來有點麻煩,還有一點排序的參數@orderby好像沒法參數化,以后有更好的方法再更新此文。
