以下面的更新用户资料为例
ALTER PROCEDURE dbo.sp_UpdateUserDetails
(
@UserID int,
@LoginPassword varchar(255) = null,
@LastLoginTime datetime = null,
@CompanyName varchar(200) = null
)
AS
declare @strSQL varchar(8000)
set @strSQL = '';
if(@UserID > 0)
begin
if(@LoginPassword is not null)
begin
set @strSQL = @strSQL + 'LoginPassword=''' + @LoginPassword + ''','
end
if(@LastLoginTime is not null)
begin
set @strSQL = @strSQL + 'LastLoginTime=''' + cast(@LastLoginTime as varchar(100)) + ''','
end
if(@CompanyName is not null)
begin
set @strSQL = @strSQL + 'CompanyName=''' + @CompanyName + ''','
end
if(len(@strSQL) > 0)
begin
set @strSQL = Left(@strSQL,LEN(@strSQL)-1)
set @strSQL = 'Update Users set ' + @strSQL + ' where UserID=' + cast(@UserID as varchar(100))
end
execute(@strSQL)
end
参数是不固定的,用字符串根据参数构造自己的sql语句,然后执行。
这么做,又没有坏处,比方说效率不高等问题,或者容易sql注入等。
如果有,应该怎么做?
ALTER PROCEDURE dbo.sp_UpdateUserDetails
(
@UserID int,
@LoginPassword varchar(255) = null,
@LastLoginTime datetime = null,
@CompanyName varchar(200) = null
)
AS
declare @strSQL varchar(8000)
set @strSQL = '';
if(@UserID > 0)
begin
if(@LoginPassword is not null)
begin
set @strSQL = @strSQL + 'LoginPassword=''' + @LoginPassword + ''','
end
if(@LastLoginTime is not null)
begin
set @strSQL = @strSQL + 'LastLoginTime=''' + cast(@LastLoginTime as varchar(100)) + ''','
end
if(@CompanyName is not null)
begin
set @strSQL = @strSQL + 'CompanyName=''' + @CompanyName + ''','
end
if(len(@strSQL) > 0)
begin
set @strSQL = Left(@strSQL,LEN(@strSQL)-1)
set @strSQL = 'Update Users set ' + @strSQL + ' where UserID=' + cast(@UserID as varchar(100))
end
execute(@strSQL)
end
参数是不固定的,用字符串根据参数构造自己的sql语句,然后执行。
这么做,又没有坏处,比方说效率不高等问题,或者容易sql注入等。
如果有,应该怎么做?
--只能用动态SQL如果要防SQL注入可以在前台把一个单引号替换成两个单引号
--用动态SQL总是影响效能的
ALTER PROCEDURE dbo.sp_UpdateUserDetails
(@UserID int,
@LoginPassword varchar(255) = null,
@LastLoginTime datetime = null,
@CompanyName varchar(200) = null)
AS
UPDATE Users
SET LoginPassword=ISNULL(@LoginPassword, LoginPassword)
,LastLoginTime=ISNULL(@LastLoginTime, LastLoginTime)
,CompanyName=ISNULL(@CompanyName,CompanyName)
WHERE UserID=@UserID
2:即使要用动态SQL,也建议使用SP_EXECUTESQL可提高性能。