Ошибка: рекурсивное общее табличное выражение 'EmailLog' не содержит оператор UNION ALL верхнего уровня - PullRequest
0 голосов
/ 13 июля 2009

Я не понимаю? Я не вижу места для выполнения «Объединения всех» в синтаксисе. Чего мне не хватает?

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 и т. Д.) Дней, и исключаю их из рассмотрения.

Ответы [ 3 ]

1 голос
/ 13 июля 2009

В исходном коде у вас есть:

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

Это единственный раз, когда вы ссылались на CTE AuditResults, и он должен быть похож на таблицу, а не на функцию. Если «Audit» в этой строке не должно быть «AuditResults» (а SapUser, вероятно, тоже vw_SapUser_Retrieve).

В любом случае, возможно, что сообщение об ошибке вводит в заблуждение из-за неправильного использования ссылки CTE.

Вы все равно это исправили, но я думаю, что вижу, что пошло не так

1 голос
/ 13 июля 2009
With EmailLog(SapUserId)
AS
(
    Select SapUserId 
    From EmailLog
    Where TypeKey = @EmailLogKey 
    And DATEDIFF(month, AttemptDate,  GETDATE()) < 2
)

Это рекурсивный CTE. Рекурсивные CTE имеют особую форму, выбирая из ахро объединения все рекурсивные части (в объединении). Вы уверены, ОТ, если правильно? Это должен быть SapUser?

0 голосов
/ 13 июля 2009

Я удалил 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...