从 SP 获取列名作为参数,并在过程中为该列设置一个值

Get the column name as a parameter from SP and set a value to that Column with in the procedure

ALTER proc [dbo].[sp_dosomethingwithStudentAttn] @AttnList as dbo.StudentAttendanceList readonly,@DeptId int,@SemId int,@SecId int,@DayId int,@currentDate date,@period nvarchar(5)
as
declare @IfStudentDayWiseAttnExists as bit,
        @updateQuery as varchar(max),
        @insertQuery as varchar(max)

begin

set nocount on
declare 
    @stnId as int,
    @stnAttnStatus as nvarchar
declare cur_UpdateInsertStnAttnData cursor  forward_only static for  
    select StudentId,AttdnStatus  from @AttnList
open cur_UpdateInsertStnAttnData
if @@CURSOR_ROWS>0
begin
    fetch next from cur_UpdateInsertStnAttnData into @stnId,@stnAttnStatus
    while @@FETCH_STATUS=0
    begin

        set @IfStudentDayWiseAttnExists=(select case when exists 
                                            (
                                                select * from tbl_DailyAttend 
                                                where DeptId=@DeptId and 
                                                SemId=@SemId and 
                                                SecId=@SecId and 
                                                attDate=@currentDate and 
                                                StuId=@stnId
                                            )
                                            then CAST(1 AS bit)
                                            else CAST(0 as bit)
                                            end
                                         )

         if @IfStudentDayWiseAttnExists='true'
         begin
            if @stnAttnStatus='true'
            begin
                select @updateQuery='update tbl_DailyAttend set '+@period+'=''true'' where DeptId='+@DeptId+' and SemId='+@SemId+' and SecId='+@SecId+' and attDate='+CONVERT(date, @currentDate)+' and StuId='+@stnId+''
                EXEC  (@updateQuery)
            end
            else
            begin
                select @updateQuery='update tbl_DailyAttend set '+@period+'=''false'' where DeptId='+@DeptId+' and SemId='+@SemId+' and SecId='+@SecId+' and attDate='+CONVERT(date, @currentDate)+' and StuId='+@stnId+''
                EXEC  (@updateQuery)
            end

         end
         else
         begin                               
            set @insertQuery='insert into tbl_DailyAttend (DeptId,SemId,SecId,DayId,attDate,'+@period+') values ('+@DeptId+','+@SemId+','+@SecId+','+@DayId+','+@currentDate+','+@stnAttnStatus+')'
         end

        fetch next from cur_UpdateInsertStnAttnData into @stnId,@stnAttnStatus
    end
end
end

由于您正在构建动态 Sql,因此您需要将语句构建为字符串 - 即您不能将日期连接到查询中 (... ='+CONVERT(date, @currentDate)+' ...)。

您还应该尽可能地尝试参数化动态查询,因为这将减少 Sql 注入面攻击区域。例如,在更新查询中,除了动态列名 (@period) 之外的所有内容都可以参数化。使用sp_executesql传递参数,跨动态查询对应类型:

DECLARE @updateQuery as NVARCHAR(max);

SELECT @updateQuery=
     N'update tbl_DailyAttend set ' + @period + N'=''true'' 
       where DeptId=@DeptId and SemId=@SemId and SecId=@SecId 
             and attDate = @currentDate and StuId=@stnId';

sp_executesql @updateQuery, 
     N'@DeptId int, 
       @SemId int, 
       @SecId int, 
       @DayId int, 
       @currentDate date,
       @stnId as int',
      @DeptId = @DeptId, 
      @SemId = @SemId, 
      @SecId = @SecId, 
      @DayId = @DayId, 
      @currentDate = @currentDate,
      @stnId = @stnId';

为了减少对动态列名的注入攻击,您还可以在执行查询之前检查该列是否存在于 table 中(例如来自 sys.columns