0

我有一个包含时间表的表,每个间隔都是该表中的一条记录(即 8:00 到 5:00。周一到周五将是该表中的 5 条记录)。我一直在研究一种可以轻松检测 SQL 查询中的重复项的方法,该查询可以创建为视图。我有一个使用游标和临时表完成工作的 SQL 查询,但游标在视图中不起作用。

我什至创建了一个存储过程来填充临时表,但我真正想做的是从视图中调用存储过程并显示结果。

如果我执行存储过程,它确实会返回预期的结果,但是我需要能够从 Select 语句中看到结果。我不能让我的用户直接执行存储过程。

这是 SP 的代码。

CREATE PROCEDURE Report_Duplicate_Schedules
AS
BEGIN
    DECLARE @Number1 AS INT, @Count1 AS INT, @ST1 AS INT, @ET1 AS INT
    DECLARE @Number2 AS INT, @Count2 AS INT, @ST2 AS INT, @ET2 AS INT
    DECLARE @Count3 AS INT

    CREATE TABLE #SchedulesDuplicates (ScheduleName NVARCHAR(100), ScheduleNumber INT, DuplicateSchedule NVARCHAR(100), DuplicateNumber INT, StartTime INT, StopTime INT);

    DECLARE Step1 CURSOR
        FOR (SELECT DISTINCT [Number], COUNT(*) AS [Count] FROM [Schedules] GROUP BY [Number])
    OPEN Step1
    FETCH NEXT FROM Step1 INTO @Number1, @Count1
    WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE Step2 CURSOR
            FOR (SELECT [Number], COUNT(*) AS [Count] FROM [Schedules] WHERE [Number] > @Number1 GROUP BY [Number])
        OPEN Step2
        FETCH NEXT FROM Step2 INTO @Number2, @Count2
        WHILE @@FETCH_STATUS = 0
        BEGIN
            IF @Count1 = @Count2
            BEGIN
                --PRINT CAST(@Number1 AS VARCHAR(50)) + N' - ' + CAST(@Count1 AS VARCHAR(50)) + N' - ' + CAST(@Number2 AS VARCHAR(50)) + N' - ' + CAST(@Count2 AS VARCHAR(50))
                SELECT @Count3 = COUNT(*) FROM 
                (SELECT [Number], [StartTime], [StopTime] FROM [Schedules] WHERE [Number] = @Number1) AS z,
                (SELECT [Number], [StartTime], [StopTime] FROM [Schedules] WHERE [Number] = @Number2) AS y
                WHERE z.[StartTime] = y.[StartTime] AND z.[StopTime] = y.[StopTime]
                IF @Count1 = @Count3
                BEGIN
                    --PRINT CAST(@Number1 AS VARCHAR(50)) + N' - ' + CAST(@Count1 AS VARCHAR(50)) + N' - ' + CAST(@Number2 AS VARCHAR(50)) + N' - ' + CAST(@Count2 AS VARCHAR(50)) + N' - ' + CAST(@Count3 AS VARCHAR(50))
                    INSERT INTO #SchedulesDuplicates ([ScheduleName], [ScheduleNumber], [DuplicateSchedule], [DuplicateNumber], [StartTime], [StopTime]) (SELECT DISTINCT u.[Name], u.[Number], v.[Name], v.[Number], v.[StartTime], v.[StopTime] FROM (SELECT [Name], [Number], [StartTime], [StopTime] FROM [Schedules] WHERE [Number] = @Number1) AS u, (SELECT [Name], [Number], [StartTime], [StopTime] FROM [Schedules] WHERE [Number] = @Number2) AS v)
                END
            END
            FETCH NEXT FROM Step2 INTO @Number2, @Count2
        END 
        CLOSE Step2
        DEALLOCATE STEP2
        FETCH NEXT FROM Step1 INTO @Number1, @Count1
    END
    CLOSE Step1
    DEALLOCATE Step1

SELECT * FROM #SchedulesDuplicates

DROP TABLE #SchedulesDuplicates

END
GO
4

1 回答 1

0

您可以尝试以下技巧:

SELECT *
FROM OPENQUERY(MyServerName, 'SET FMTONLY OFF EXEC database.dbo.procedure')

几点注意事项:

  • 应该在服务器上启用 DATAACCESS 选项
  • 正确的列元数据检索最需要 SET FMTONLY
  • 过程应该在开头有 SET NOCOUNT ON 语句,没有它元数据检索失败

但是,我建议您逐行重写此处理逻辑以设置基于代码的代码,这很容易适应普通视图。表值用户定义函数也可以完成这项工作。

于 2012-10-15T18:18:40.823 回答