摘要
是否有一种有效的方法来运行大量的动态SQL(在SQL Server 2005上)?
详情
我们的系统允许用户创建“电子邮件提醒”订阅 - 系统上的新匹配每天通过电子邮件发送给他们。
订阅允许多种选项,包括使用搜索关键字。我自己编写的解析器会输出相应的SQL代码,并考虑and
,or
和方括号()
。 解析器将不允许任何可用于SQL注入的内容。
例如,用户可能会将关键字输入为this (that or other)
,结果查询最终会大致为......
SELECT *
FROM [VW_EMAIL_ALERT]
WHERE ([SEARCH] LIKE '%this%' AND ([SEARCH] LIKE '%that%' OR [SEARCH] LIKE '%other%'))
每晚,所有订阅都会单独处理,因为每个订阅都可能是唯一的。结果是批处理必须在每个订阅上运行游标并通过sp_executesql
运行SQL。
显然这是非常低效的,并且可能导致严重的超载 - 在某些情况下导致超时。运行此处理的存储过程被编码为将订阅拆分为块,因此不会立即调用它们。
有更好/更有效的方法吗?
注意:遗憾的是,我们目前仍然支持最少的SQL Server 2005,因为我们的一些客户仍然使用该技术
答案 0 :(得分:1)
如果您正在寻找效率最低的关键字,那么您可以这样做 类似'%任何东西不使用索引
使用FullText搜索索引单词
或者编写自己的解析器来索引唯一的单词
你会建立一个关键词表
并索引关键字
这是一个非常有效的查询
select id
from keywords
where keyword = 'this'
intersect
select id
from keywords
where keyword in ( 'that','other')
即使在关键字中使用通配符,它仍然比搜索整个文本更有效
答案 1 :(得分:0)
我希望这会有所帮助。在我的工作中,我们用这种实现替换了光标。
DECLARE
@strSQL NVARCHAR(MAX) = ''
CREATE TABLE #tmp
(
Result_Query VARCHAR(MAX)
)
INSERT INTO
#tmp
SELECT
'SELECT * FROM [VW_EMAIL_ALERT] WHERE ([SEARCH] = ''%this%'' AND ([SEARCH] = ''%that%'' OR [SEARCH] = ''%other%''))'
UNION
SELECT
'SELECT * FROM [VW_EMAIL_ALERT] WHERE ([SEARCH] = ''%this1%'' AND ([SEARCH] = ''%that1%'' OR [SEARCH] = ''%other1%''))'
SELECT
@strSQL = @strSQL + Result_Query + ';'
FROM
#tmp
SET
@strSQL = LEFT(@strSQL, LEN(@strSQL) - 1)
PRINT @strSQL
EXEC(@strSQL)