2011-05-16 50 views
1

我已經寫在程序爲:有關SQL IN功能

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 ('[email protected]_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)+'. 

,當我試圖解決這個問題,我不能讓我的願望的結果。所以任何一個在那裏解決這個

+0

爲什麼你運行動態TSQL時,你似乎不需要這樣做? – 2011-05-16 06:31:13

+0

很可能他在'@ emp_id'中使用逗號分隔empid。 – TheVillageIdiot 2011-05-16 06:32:59

+0

@TheVillageIdiot:啊是的!錯過了那一點....然後將它們分解到一個臨時表並加入它。或者處理CSV ID值的許多其他方法之一 – 2011-05-16 06:42:54

回答

1

要避免使用動態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 

一個函數,那麼你可以在你想在你使用IN子句像一個逗號分隔列表中的值發送。然後在你的where子句中,你可以做

WHERE emp_id in (SELECT CONVERT(int, items) FROM dbo.Split(@emp_id, ',')) ... 

這樣你就不必做動態SQL,查詢優化器可以做得更好。

1

最有可能它是報價問題。 嘗試用這樣的雙引號替換所有單引號。

編輯: - 您正在嘗試使用aliasCAST功能不允許的。

錯誤

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 ('[email protected]_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 
+0

您的代碼已成功編譯,但是當我執行過程爲=> exec proc_sample @ emp_id ='206,506'它顯示以下錯誤:消息170,級別15,狀態1,行10 第10行:'and'附近的語法錯誤。 – Nhuren 2011-05-16 07:07:40

+0

@Nhuren @inquam在他的回答中給出了正確的方法,我的團隊也使用它(將字符串拆分並放入臨時表)。實際上傳遞的ID字符串也被包裹在'所以它不起作用。對不起有沒有時間檢查和糾正我的錯誤。 – TheVillageIdiot 2011-05-16 17:10:30