我有一个存储过程,其中的参数看起来像这样
Create Procedure [dbo].[myStoredProcedure]
@TaskId int = 0
, @FileName varchar(200) =''
, @DataDtFrom smalldatetime = '01/01/1900'
, @DataDtTo smalldatetime = '01/01/1900'
, @OFFSET INT = 0
, @FETCH INT = 2000
, @WhereClauseString varchar(5000) = ''
SELECT
DataDt
,EffDt
,LoanNumber
,UploadDate
,UploadedFileName
FROM dbo.myFileTable u
WHERE
(@DataDtTo = '01/01/1900' or DataDt between @DataDtFrom and @DataDtTo)
and (@TaskId = 0 or TaskId = @TaskId)
and (@FileName = '' or UploadedFileName like '%' + @FileName + '%')
**Where ??? = @WhereClauseString**
ORDER BY u.UploadDate
OFFSET @OFFSET ROWS
FETCH NEXT @FETCH ROWS ONLY
我用C#初始化
var whereClauseString = "LoanNum in(111,222,444) and TaskId in (123,456,789)";
using (var conn = new MyEntities().Database.Connection)
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandTimeout = 1800;
cmd.CommandText = model.UploadStoredProcedure;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@TaskId", Convert.ToInt64(model.TaskId)));
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@FileName", model.FileName ?? string.Empty));
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@DataDtFrom", DateTime.Parse(model.adjFromDataDt.ToShortDateString()) <= DateTime.Parse(basicDate.ToShortDateString()) ? basicDate : model.adjFromDataDt.Date));
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@DataDtTo", DateTime.Parse(model.adjToDataDt.ToShortDateString()) <= DateTime.Parse(basicDate.ToShortDateString()) ? basicDate : model.adjToDataDt.Date));
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@OFFSET", model.Page));
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@FETCH", model.PageSize));
**Dynamic Where clause** -->> System.Data.SqlClient.SqlParameter("@WhereClause", whereClauseString));
var da = new System.Data.SqlClient.SqlDataAdapter((System.Data.SqlClient.SqlCommand)cmd);
da.Fill(ds);
}
我的问题是可以构建动态的where子句并将其传递给存储过程,然后对where子句中引用的列进行排序吗? 我如何知道在存储过程中需要在where子句中引用的列?
使用此存储过程和实体框架是否有可能?
答案 0 :(得分:1)
无论如何,如果您的数据库远离SQL注入的外部攻击,您仍然可以考虑使用基于Dinamic SQL的简单解决方案,那么这种方法通常可以快速解决非常复杂的问题,否则:
CREATE Procedure [dbo].[myStoredProcedure]
@TaskId int = 0
, @FileName varchar(200) =''
, @DataDtFrom smalldatetime = '01/01/1900'
, @DataDtTo smalldatetime = '01/01/1900'
, @OFFSET INT = 0
, @FETCH INT = 2000
, @WhereClauseString varchar(5000) = ''
AS
BEGIN
DECLARE @SQL AS NVARCHAR(MAX);
SELECT @SQL = '
SELECT
DataDt
,EffDt
,LoanNumber
,UploadDate
,UploadedFileName
FROM dbo.myFileTable u
WHERE
('''+CONVERT(CHAR(10), @DataDtTo, 112)+''' = ''01/01/1900'' or DataDt between '''+CONVERT(CHAR(10), @DataDtFrom, 112)+''' and '''+CONVERT(CHAR(10), @DataDtTo, 112)+''')
and ('+CONVERT(CHAR(10), @TaskId)+' = 0 or TaskId = '+CONVERT(CHAR(10), @TaskId)+')
and ('+RTRIM(CONVERT(CHAR(100), @FileName))+' = '''' or UploadedFileName like ''%'+RTRIM(CONVERT(CHAR(100), @FileName))+'%'')
' +CONVERT(CHAR(100), @WhereClauseString)+'
ORDER BY u.UploadDate
OFFSET '+CONVERT(CHAR(10), @OFFSET)+' ROWS
FETCH NEXT '+CONVERT(CHAR(10), @FETCH)+' ROWS ONLY;
'
PRINT @SQL;
EXEC sp_ExecuteSQL @SQL;
END;