2

SQlサーバーでCTE包含を書き込む方法を知りたいだけですか?If Exists以下にCTEを書き込もうとしましたが、If Existsステートメントを使用してレコードが存在するかどうかを選択しています。レコードが存在しない場合は、デフォルト値を割り当てていますが、エラーが発生します。

'キーワードの近くの構文が正しくありません'if'

。」このエラーを修正し、このCTEを作成するように案内してください。私が書いたCTEの下を見つけてください:-

Alter procedure St_Proc_GetTeamProductionReport      
@mindate DateTime,                        
@maxdate DateTIme,    
@userID varchar(50)                    
as                                          
Begin                                          
     set NoCount on; 
with    
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)    
as    
(    
    if exists
    (
        select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,    
        R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment    
        from production P inner join NatureOfWork N    
        on N.NatureofWorkID=P.natureofworkid    
        inner join dbo.RegionAndProjectInfo R    
        on R.RegionProjectID=P.RegionProjectID    
        inner join county C    
        on C.countyid=P.countyid    
        inner join worktype W    
        on W.Worktypeid=P.worktypeID    
        inner join task T    
        on T.taskid=P.TaskID    
        inner join UserInfo U    
        on U.Userid=P.userid    
        where P.userid=@userID  and ( convert(varchar, P.CalendarDate, 101) )  between (
        convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )  
    )
    else
    (
        Select '2012-09-14 13:41:52' as CalendarDate,
        2 as RoleID,'938' as UserID,
        (select Userecode from Userinfo where userid=@userID) as UserECode,
        (select UserName from Userinfo where userid=@userID)as UserName,
        (select ImmediateSupervisor from Userinfo where userid=@userID)as ImmediateSupervisor,
        'BP' as NatureOfWorkName,
        'CO Processing' as RegionProjectName,
        'Adams' as CountyName,
        'Quality' as WorkTypeName,
        'Corrections ' as TaskName,
        5 as VolumneProcessed,
        '01:00' as TimeSpent,
        'test' as Comment
        ) 

    union all

    select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,    
    R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment    
    from production P inner join NatureOfWork N    
    on N.NatureofWorkID=P.natureofworkid    
    inner join dbo.RegionAndProjectInfo R    
    on R.RegionProjectID=P.RegionProjectID    
    inner join county C    
    on C.countyid=P.countyid    
    inner join worktype W    
    on W.Worktypeid=P.worktypeID    
    inner join task T    
    on T.taskid=P.TaskID    
    inner join UserInfo U    
    on U.Userid=P.userid    
    inner join ProductionCTE    
    on U.ImmediateSupervisor=ProductionCTE.UserECode    

    where P.IsTaskCompleted=1   and ( convert(varchar, P.CalendarDate, 101) )  between (
    convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )         
)  
select  distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment from ProductionCTE where  RoleID=1    
end

行く

このIfExistステートメントを削除すると、CTEは正常に機能しますが、ステートメントを追加した後、IF Existsエラーが発生します。

4

3 に答える 3

2

このままでは使えませんIF EXISTS。共通テーブル式には、select ステートメントを 1 つだけ含める必要がありますif condition SELECT THIS else SELECT THAT

クエリによって返された結果セットに追加の作成された行を追加しようとしているようです。これは、単一の新しい行を返すテーブル値関数として CTE を実装することで実現できます。

http://msdn.microsoft.com/en-gb/library/ms191165(v=sql.105).aspx

于 2013-02-06T11:23:08.680 に答える
1

最初の結果が行を返さない場合にUNION2 番目の結果のみを取得するを構築する場合は、 を使用してこれを実現できます。したがって、実際のクエリを最初に配置し、目的のデフォルト値を 2 番目に配置して、必要な結果を得ることができます。SELECTSELECTRANK()SELECT

私はあなたのテーブルとデータを持っていないので、あなたのクエリを書き直すつもりはありません。しかし、私はこれで説明します:

;With WithDefaults as (
    select name,0 as Rank from sys.objects
    union all
    select 'abc',1 --Default if no results
), Ranked as (
    select *,RANK() OVER (ORDER BY Rank) as Rnk from WithDefaults
)
select * from Ranked where Rnk = 1

(私が試したほとんど空のDBで)98の結果を返しますが、name abc. SELECT最初に結果を返さないように強制すると、次のようになります。

    select name,0 as Rank from sys.objects where 1 = 2

.で単一行の結果が得られますname abc

うまくいけば、これが元のクエリにどのように適用されるかがわかります。

于 2013-02-06T13:51:04.723 に答える
0

CTE で IF EXISTS を使用することはできません。ただし、関数のロジックを変更できます

例:

alter procedure St_Proc_GetTeamProductionReport
@mindate DateTime,                        
@maxdate DateTIme,    
@userID varchar(50)                    
as                                          
Begin                                          
set NoCount on;
;with    
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)    
as    
(               
        select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,    
        R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment, 1 AS cnt 
        from production P inner join NatureOfWork N    
        on N.NatureofWorkID=P.natureofworkid    
        inner join dbo.RegionAndProjectInfo R    
        on R.RegionProjectID=P.RegionProjectID    
        inner join county C    
        on C.countyid=P.countyid    
        inner join worktype W    
        on W.Worktypeid=P.worktypeID    
        inner join task T    
        on T.taskid=P.TaskID    
        inner join UserInfo U    
        on U.Userid=P.userid    
        where P.userid=@userID  and ( convert(varchar, P.CalendarDate, 101) )  between (
        convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )  
        UNION ALL
        Select '2012-09-14 13:41:52' as CalendarDate,
        2 as RoleID,'938' as UserID,
        (select Userecode from Userinfo where userid=@userID) as UserECode,
        (select UserName from Userinfo where userid=@userID)as UserName,
        (select ImmediateSupervisor from Userinfo where userid=@userID)as ImmediateSupervisor,
        'BP' as NatureOfWorkName,
        'CO Processing' as RegionProjectName,
        'Adams' as CountyName,
        'Quality' as WorkTypeName,
        'Corrections ' as TaskName,
        5 as VolumneProcessed,
        '01:00' as TimeSpent,
        'test' as Comment, 0 
     ), ProductionCTE2 AS    
    (    
    SELECT TOP(SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE COUNT(*) END FROM ProductionCTE WHERE cnt = 1)
           CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureofWorkName,    
           RegionProjectName,Countyname,WorktypeName,TaskName,VolumeProcessed,Timespent,Comment
    FROM ProductionCTE2           
    union all
    select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,    
    R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment    
    from production P inner join NatureOfWork N    
    on N.NatureofWorkID=P.natureofworkid    
    inner join dbo.RegionAndProjectInfo R    
    on R.RegionProjectID=P.RegionProjectID    
    inner join county C    
    on C.countyid=P.countyid    
    inner join worktype W    
    on W.Worktypeid=P.worktypeID    
    inner join task T    
    on T.taskid=P.TaskID    
    inner join UserInfo U    
    on U.Userid=P.userid    
    inner join ProductionCTE    
    on U.ImmediateSupervisor=ProductionCTE.UserECode
    where P.IsTaskCompleted=1   and ( convert(varchar, P.CalendarDate, 101) )  between (
    convert(varchar, @mindate, 101) ) and ( convert(varchar, @maxdate, 101) )         
)  
select  distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment 
from ProductionCTE2
where  RoleID=1    
end
于 2013-02-06T13:34:01.627 に答える