错误:递归公用表表达式'EmailLog'不包含顶级UNION ALL运算符

时间:2009-07-13 06:27:54

标签: tsql

我不明白吗?我没有看到在语法中执行“Union All”的任何地方。我错过了什么?

CREATE PROCEDURE SapUser_NdaysBeforeExpirationNotification
    -- Add the parameters for the stored procedure here
(
    @AuditTypeKey nvarchar(50),
    @TimeLapseInMonths int
)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    With AuditResults(SapUserId)
    AS
    (
        Select SapUserId From Audit
        Where TypeKey = @AuditTypeKey And DATEDIFF(month, AttemptDate,  GETDATE()) < 2
    )


    Select * from SapUser 
    Inner Join Audit On vw_SapUser_Retrieve.SapId <> AuditResults.SapUserId
    Where DATEDIFF(month, OriginalTrainingDate,  GETDATE()) > @TimeLapseInMonths 

END

审核表(又名EmailLog)

CREATE TABLE [dbo].[Audit](
    [AuditId] [int] NOT NULL,
    [TypeKey] [nvarchar](50) NOT NULL,
    [Description] [nvarchar](250) NULL,
    [AuditDate] [datetime] NOT NULL,
    [SapUserId] [int] NOT NULL,
 CONSTRAINT [PK_EmailLog] PRIMARY KEY CLUSTERED 

SapUser表

CREATE TABLE [dbo].[SapUser](
    [SapId] [int] IDENTITY(70000,1) NOT NULL,
    [Username] [nvarchar](10) NULL,
    [Password] [nvarchar](50) NOT NULL,
    [FirstLogin] [bit] NOT NULL,
    [Roles] [tinyint] NOT NULL,
    [Status] [nvarchar](20) NOT NULL,
    [Title] [nvarchar](20) NULL,
    [FirstName] [nvarchar](50) NOT NULL,
    [LastName] [nvarchar](50) NOT NULL, 

...等

问题详情

我有两张桌子:SapUser和EmailLog。在特定时间范围内,如果用户未采取措施,他们的帐户将被删除。因此,在90,60,30,7,1天递增时,我发送一封电子邮件,提醒他们采取行动。

每次发送电子邮件时,我都会将其记录在“审核”表中(电子邮件地址为emaillog)。因为并非所有月份都是30天,所以一个人可能会收到两个90天的通知。为了防止这种情况,我在Audit表中插入一行。

当我运行例程来查找要发送电子邮件的帐户时,我首先找到审核表中的所有帐户,我在最后N(90,60,30 ..etc)天内发送电子邮件并将其从考虑中删除。

3 个答案:

答案 0 :(得分:1)

With EmailLog(SapUserId)
AS
(
    Select SapUserId 
    From EmailLog
    Where TypeKey = @EmailLogKey 
    And DATEDIFF(month, AttemptDate,  GETDATE()) < 2
)

这是递归CTE。递归CTE具有特定形式,从achro union中选择所有递归部分(在连接中)。你确定FROM是否正确?它应该是SapUser吗?

答案 1 :(得分:1)

在原始代码中,您有:

Select * from SapUser 
Inner Join Audit On vw_SapUser_Retrieve.SapId <> AuditResults.SapUserId
Where DATEDIFF(month, OriginalTrainingDate,  GETDATE()) > @TimeLapseInMonths 

这是您唯一一次引用CTE AuditResults,它应该像一个表,而不是一个函数。除非此行中的“审核”应为“AuditResults”(并且SapUser可能也是vw_SapUser_Retrieve)。

无论如何,由于错误地使用了CTE引用,错误消息可能会产生误导。

你已经修好了,但我想我能看出出了什么问题

答案 2 :(得分:0)

我删除了CTE并创建了一个SQL语句。我相信这是一回事,CTE更容易理解。希望我有一个正确的SQL语句。

Select  * from vw_SapUser_Retrieve 
Inner Join Audit On vw_SapUser_Retrieve.SapId = Audit.SapUserId
Where DATEDIFF(month, OriginalTrainingDate,  GETDATE()) > @TimeLapseInMonths AND (Audit.TypeKey <> @AuditTypeKey OR (Audit.TypeKey = @AuditTypeKey AND DATEDIFF(month, Audit.AuditDate,  GETDATE()) > 2))