0

スケジュールを含むテーブルがあり、各間隔はそのテーブルの1つのレコードです(つまり、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は、ほとんどの場合、正しい列のメタデータを取得するために必要です。
  • プロシージャには、メタデータの取得に失敗することなく、最初にSETNOCOUNTONステートメントが必要です。

ただし、この行を行処理ロジックで書き直して、通常のビューに簡単に収まるベースのコードを設定することをお勧めします。テーブル値のユーザー定義関数もその役割を果たします。

于 2012-10-15T18:18:40.823 に答える