我传递给存储过程以填充我的DT的一个参数是电子邮件地址。如果电子邮件地址有('),那么DT将填充没有数据。
但是,我确实逃过了(')所以我知道这不太可能是问题所在:
我想为什么('')或('''')的存在会导致调用不成功,即使存储过程运行?如果我有办法解决这个问题?
我尝试的事情:
在为参数赋值之前转义'
if (searchTermValue.Contains('\''))
searchTermValue = searchTermValue.Replace("'", "''''");
在SQL存储过程中转义('):
SET @searchTerm = REPLACE(@searchTerm,CHAR(39), CHAR(39) + CHAR(39) + CHAR(39) + CHAR(39))
当我从代码中调用它时,我仍然无法使存储过程返回数据。当@searchTerm有'。对存储过程的调用是标准的:
{ SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "rpt_EmailSearch";
cmd.Parameters.Add(new SqlParameter("@FilterBy", string.Empty));
cmd.Parameters.Add(new SqlParameter("@FilterType", FilterType));
cmd.Parameters.Add(new SqlParameter("@searchTerm", searchTerm));
cmd.Parameters.Add(new SqlParameter("@BaseChannelID", BaseChannelID));
cmd.Parameters.Add(new SqlParameter("@currentPage", currentPage));
cmd.Parameters.Add(new SqlParameter("@pageSize", pageSize));
cmd.Parameters.Add(new SqlParameter("@SortBy", sortColumn + " " + sortDirection));
return DataFunctions.GetDataTable(cmd, DataFunctions.ConnectionString.Communicator.ToString());}
public static DataTable GetDataTable(SqlCommand cmd,string connectionStringName) { DataTable dt = new DataTable();
using (SqlConnection conn = DataFunctions.GetSqlConnection(connectionStringName))
{
cmd = MinDateCheck(cmd);
cmd = MinTimeCheck(cmd);
cmd.Connection = conn;
cmd.CommandTimeout = 0;
try
{
cmd.Connection.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
dt.Load(dr);
}
catch (Exception)
{
throw;
}
finally
{
if (cmd != null)
{
cmd.Connection.Close();
cmd.Dispose();
}
}
}
return dt;
}
这是proc本身:
declare
--Payload filters
@FilterBy varchar(50) = '',
@FilterType varchar(50) = 'like',
@searchTerm varchar(MAX) = '', ---THIS IS THE PARAMETER WHERE I SUPPLY 'o'test@mail.com' VALUE
@BaseChannelID int = 92,
--Sort filters
@CurrentPage int = 1,
@PageSize int = 15,
@SortBy VARCHAR(30) = 'EmailAddress DESC',
--Local variables
@EmailPart varchar(MAX) = '',
@ChannelPartOne varchar(MAX) = '',
@ChannelPartTwo varchar(MAX) = ''
SET @searchTerm = REPLACE(@searchTerm,CHAR(39), CHAR(39) + CHAR(39) + CHAR(39) + CHAR(39))
IF @FilterType = 'equals'
BEGIN
SET @EmailPart = 'AND e.EmailAddress = ''' + @searchTerm + ''''
END
IF @FilterType = 'starts'
BEGIN
SET @EmailPart = 'AND e.EmailAddress like ''' + @searchTerm + '%'''
END
IF @FilterType = 'like'
BEGIN
SET @EmailPart = 'AND e.EmailAddress like ''%' + @searchTerm + '%'''
END
IF @FilterType = 'ends'
BEGIN
SET @EmailPart = 'AND e.EmailAddress like ''%' + @searchTerm + ''''
END
IF @BaseChannelID <> 0
BEGIN
SET @ChannelPartOne = 'AND bc.BaseChannelID = ' + CONVERT(varchar(10), @BaseChannelID)
SET @ChannelPartTwo = 'AND e.BaseChannelID = ' + CONVERT(varchar(10), @BaseChannelID)
END
CREATE TABLE #tmp (
BaseChannelName varchar(100),
CustomerName varchar(100),
GroupName varchar(100),
EmailAddress varchar(100),
SubscribeTypeCode varchar(100),
DateCreated datetime,
DateModified datetime
)
EXEC ('
INSERT INTO #tmp
select
bc.BaseChannelName,
c.CustomerName,
g.GroupName,
e.EmailAddress,
case when eg.SubscribeTypeCode = ''S'' then ''Subscribed''
when eg.SubscribeTypeCode = ''U'' then ''Unsubscribed''
when eg.SubscribeTypeCode = ''P'' then ''Pending''
when eg.SubscribeTypeCode = ''D'' then ''Bad Record''
when eg.SubscribeTypeCode = ''M'' then ''Master Suppressed'' else eg.SubscribeTypeCode end as ''Subscribe'',
eg.CreatedOn as ''DateCreated'', eg.LastChanged as ''DateModified''
from
Emails e with (nolock)
join ECN5_ACCOUNTS..Customer c with (nolock) on e.CustomerID = c.CustomerID and c.IsDeleted = 0
join ECN5_ACCOUNTS..Basechannel bc with (nolock) on c.BaseChannelID = bc.BaseChannelID and bc.IsDeleted = 0
join EmailGroups eg with (nolock) on e.EmailID = eg.EmailID
join Groups g with (nolock) on eg.GroupID = g.GroupID and IsNull(g.MasterSupression, 0) = 0
where
1=1
' + @ChannelPartOne + '
' + @EmailPart + '
UNION
select
bc.BaseChannelName, '''' as ''CustomerName'', '''' as ''GroupName'', EmailAddress, ''Channel Suppressed'' as ''Subscribe'', e.CreatedDate as ''DateCreated'', e.UpdatedDate as ''DateModified''
from
ChannelMasterSuppressionList e with (nolock)
join ECN5_ACCOUNTS..Basechannel bc with (nolock) on e.BaseChannelID = bc.BaseChannelID and bc.IsDeleted = 0
where
e.IsDeleted = 0
' + @ChannelPartTwo + '
' + @EmailPart + '
order by ' + @SortBy
);
WITH Results
AS (SELECT
ROW_NUMBER() OVER (ORDER BY @SortBy
) AS ROWNUM,
COUNT(*) OVER () AS TotalCount,
*
FROM #tmp)
SELECT
*
FROM Results
WHERE ROWNUM BETWEEN ((@CurrentPage - 1) * (@PageSize + 1)) AND (@CurrentPage * @PageSize)
DROP TABLE #tmp
END
一个更多的更正:这个不运行动态SQL的proc版本运行速度非常慢(动态SQL大约需要6秒,没有动态SQL大约需要150秒)所以我现在必须恢复到上面的版本。
谢谢!
答案 0 :(得分:0)
好的,弄明白为什么没有回来: 当执行命令时,(&#39;)被自动替换为(&#39;&#39;)所以在代码中执行替换会创建在任何地方找不到匹配项的参数D B。 但是,我必须在SQL中执行Replace,如下所示;因为否则动态SQL不能形成proc:
SET @searchTerm = REPLACE(@searchTerm,CHAR(39), CHAR(39) + CHAR(39))
我的错误是我不知道sql命令的自动替换。 谢谢大家的回答!