使用动态sql的替代方法

时间:2012-08-21 15:22:07

标签: sql tsql stored-procedures

我有一个输入@featuretype的sp。 @featuretype将等于“mobile”,“login”或“index”,并且将对应于db中的列。

在我的sp中我有:

EXEC(
    'select TOP 3 * from featuredtypes_v where'+' featuredtypes_v.'+@featuretype+'Page=1'+
    ' order by featuredtypes_v.priority desc'
    )

然而,我被告知这会打开db到sql注入。我的两个问题是,为什么会这样,以及如何编写此查询以避免这种情况?

4 个答案:

答案 0 :(得分:6)

为什么不使用case

select TOP 3 * 
from featuredtypes_v F
where
    case
        when @featuretype = 'mobile' then F.MobilePage
        when @featuretype = 'login' then F.LoginPage
        when @featuretype = 'index' then F.IndexPage
    end
    = 1

答案 1 :(得分:3)

如果用户提供传递给变量的值,或者有人找到执行传入特制恶意代码的存储过程的方法,则您的过程将打开。谷歌我的用户名是一个有趣的漫画基于此。

由于您在存储过程中,可以检查变量,然后根据提供的变量执行SELECT语句:

IF @featuretype = 'mobile'
BEGIN
    select TOP 3 * 
    from featuredtypes_v 
    where featuredtypes_v.MobilePage=1
    order by featuredtypes_v.priority desc
END
IF @featuretype = 'login'
BEGIN
    select TOP 3 * 
    from featuredtypes_v 
    where featuredtypes_v.LoginPage=1
    order by featuredtypes_v.priority desc
END
-- etc...

或者,您可以将WHERE子句中的条件放在一个查询中:

select TOP 3 * 
from featuredtypes_v 
where (featuredtypes_v.MobilePage=1 AND @featuretype = 'Mobile') OR 
    (featuredtypes_v.LoginPage=1 AND @featuretype = 'Login') OR
    (featuredtypes_v.IndexPage=1 AND @featuretype = 'Index')
order by featuredtypes_v.priority desc

答案 2 :(得分:1)

一种方法就是这样。确保表中存在该列,然后执行动态sql,否则不执行。

if Exists(select * from sys.columns where Name = N'@featuretype'  
            and Object_ID = Object_ID(N'tableName'))
begin

   EXEC(
    'select TOP 3 * from featuredtypes_v where'+' featuredtypes_v.'+@featuretype+'Page=1'+
    ' order by featuredtypes_v.priority desc'
    )

end

答案 3 :(得分:0)

你们都没有回答这个问题。 这是somthing sql注入可能发生

underlyingQueue

现在如果txtUser = 105或1 = 1那么sql语句将是这样的

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

使用sql参数避免sql注入。它验证字符串和sql执行alwaus就像它想象的那样