关于函数中的sql

关于函数中的sql,sql,tsql,Sql,Tsql,我已将程序写为: create proc proc_sample @emp_id as nvarchar(500) as begin declare @sql as varchar(500) set @sql=' select tdate,emp_id, max(convert(varchar(40),DateDiff(minute,cast(tdate + ' ' +intime as datetime), Cast(isnull(tdate_out,tdate) +

我已将程序写为:

create proc proc_sample

@emp_id as nvarchar(500)
as
begin
declare @sql as varchar(500)

set @sql='
select tdate,emp_id, 
    max(convert(varchar(40),DateDiff(minute,cast(tdate + ' ' +intime as datetime), 
    Cast(isnull(tdate_out,tdate)  + ' ' +outtime as datetime))%(24*60)/60)+ 'hrs'+
    convert(varchar(40),DateDiff(minute,cast(tdate + ' ' +intime as datetime),  
    Cast(isnull(tdate_out,tdate)  + ' ' +outtime as datetime))%60)+ 'min')
    as [Worked Hour],max(intime),max(outtime),max(inremarks)
from tbl_emp_attn_log 
where emp_id in ('+@emp_id+')and tdate 
     between '2010-1-01 00:00:00' and '2011-04-09 00:00:00'  
group by tdate,emp_id order by emp_id,tdate'
end
但它显示了以下错误:

Msg 170, Level 15, State 1, Procedure proc_sample, Line 10
Line 10: Incorrect syntax near ' +intime as datetime), Cast(isnull(tdate_out,tdate)+'.
当我试图解决这个问题时,我没有得到我想要的结果。所以任何一个解决这个问题的人都很可能是引用的问题。尝试将中的所有单引号替换为双引号,如下所示

编辑:-您试图在
CAST
功能中使用
alias
,这是不允许的

错误

cast(tdate + ' ' +intime as datetime)
正确

cast(tdate as datetime)
修改的查询

create proc proc_sample

@emp_id as nvarchar(500)
as
begin
declare @sql as varchar(500)

set @sql='
select tdate,emp_id, 
    max(convert(varchar(40),DateDiff(minute,cast(tdate as datetime), 
    Cast(isnull(tdate_out,tdate) as datetime))%(24*60)/60)+ ''hrs''+
    convert(varchar(40),DateDiff(minute,cast(tdate as datetime),  
    Cast(isnull(tdate_out,tdate) as datetime))%60)+ ''min'')
    as [Worked Hour],max(intime),max(outtime),max(inremarks)
from tbl_emp_attn_log 
where emp_id in ('+@emp_id+')and tdate 
     between ''2010-1-01 00:00:00'' and ''2011-04-09 00:00:00''  
group by tdate,emp_id order by emp_id,tdate'
end

为了避免使用动态SQL,从而失去存储过程的一些功能,您可以使用如下函数

CREATE FUNCTION dbo.Split(@String varchar(8000), @Delimiter char(1))       
returns @temptable TABLE (items varchar(8000))       
as       
begin       
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return       
end  

这样,您就不必使用动态SQL,查询优化器可以做得更好。

为什么在您似乎不需要运行动态TSQL的情况下运行动态TSQL?很可能他在
@emp\u id
@TheVillageIdiot中得到了逗号分隔的emp id:啊,是的!错过了这一点…然后把他们分成一个临时表并加入其中。或者其他许多处理CSV ID值的方法之一实际上@emp_ID包含逗号分隔的ID,如:@emp_ID='203509,…'您的代码已成功编译,但当我以=>exec proc_sample@emp_ID='206506'执行过程时,它显示以下错误:Msg 170,级别15,状态1,第10行第10行:“and”附近的语法不正确。@Nhuren正确的方法是@inquam在他的回答中给出的,我的团队也使用这种方法(拆分字符串并将其放入临时表)。实际上,传递的ID字符串也被包装在“中”,因此它不起作用。很抱歉,我没有时间检查并纠正我的错误。
WHERE emp_id in (SELECT CONVERT(int, items) FROM dbo.Split(@emp_id, ',')) ...