DECLARE tableList CURSOR FOR
SELECT t.name
FROM sys.tables t
INNER JOIN sys.columns c
ON t.object_id = c.object_id
WHERE
t.name NOT LIKE 'z%'
AND t.name NOT LIKE '%delete%'
AND t.name <> 'tblUsers'
AND t.name <> 'tblUserLogins'
AND t.name <> 'searchR'
AND t.name <> 'tblUserPortfolio'
AND t.name <> 'alerts_User'
AND c.name LIKE 'userid'
OR c.name LIKE 'user_id'
ORDER BY name
OPEN tableList
FETCH NEXT FROM tableList
INTO @tablename
上面是构建游标的查询,它使用了很多LIKE
,NOT LIKE
个操作,我认为这些操作可能很昂贵。
所以我问是否有更好的方法来构建查询而不使用太多LIKE/NOT LIKE
并使其更优化。
感谢。
编辑:
此处使用游标的目的是Loop Through
所有匹配的表,以便我们可以动态插入/更新/删除记录。
我正在使用的数据库中有超过150个表,所以我认为sql server也可以做脏工作。
答案 0 :(得分:5)
我会:
1)使用NOT IN代替多个“...和t.name&lt;&gt; ...”,使SQL更具可读性(IMO) 2)将c.name LIKE更改为单个IN子句,因为您似乎想要完全匹配,不需要LIKE
SELECT t.name
FROM sys.tables t
INNER JOIN sys.columns c ON t.object_id = c.object_id
WHERE t.name NOT LIKE 'z%' AND t.name NOT LIKE '%delete%'
AND t.name NOT IN ('tblUsers','tblUserLogins','searchR','tblUserPortfolio','alerts_User')
AND c.name IN ('userid','user_id')
ORDER BY name
这实际上不太可能在性能方面做出很多不同,但我认为它使其更具可读性/可维护性。
但是,我要提出的要点是你是否真的需要一个光标 - 我绝对希望将其删除,而采用基于集合的方法。虽然需要知道你在光标中做了什么,以便提出一个替代方案。
修改强> 您可以尝试这种动态生成SQL并一次执行它的方法(简单示例,假设您希望将相同的行插入到每个具有相同结构的表中)。很难知道这是否真的适合你的确切场景(或者它是否真的会产生有价值的差异),但知道这种技术会很有用。
DECLARE @nSQL NVARCHAR(MAX)
SELECT @nSQL = COALESCE(@nSQL, '') +
'INSERT ' + QUOTENAME(t.name) + '([SomeCol]) VALUES (@ValueToInsert);' + CHAR(10)
FROM sys.tables t
INNER JOIN sys.columns c ON....
...{rest of current SELECT)
-- comment out PRINT, and uncomment EXECUTE statement to actually run the SQL
PRINT @nSQL
-- EXECUTE sp_executesql @nSQL, N'@ValueToInsert VARCHAR(10)', 'NewValue'