Где можно разместить сценарий SQL, который создает временные таблицы и разрешает объединения? - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть сценарий, который в идеале должен жить в представлении, но поскольку он создает временную таблицу, SQL Server не позволяет этого.

Мне нужно иметь возможность вызывать его и создавать соединения из различныххранимые процедуры, поэтому было бы хорошо, чтобы они содержались в одном месте, если необходимо внести изменения, а не встраивать их повсеместно.Я не думаю, что хранимая процедура будет работать, потому что я не верю, что вы можете присоединиться к наборам результатов SP.

Что будет работать?

Вот сценарий:

DECLARE @fiscalPeriod smalldatetime,
        @openingUnits float,
        @divPrice money,
        @divFactor float,
        @drip float,
        @endingUnits float


DECLARE divCursor CURSOR FOR
SELECT [FiscalPeriod]
      ,[SharePrice]
      ,[Rate]
  FROM [dbo].[Pricing]
  ORDER BY FiscalPeriod

OPEN divCursor

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

SET @openingUnits = 1
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

SELECT FiscalPeriod = @fiscalPeriod, OpeningUnits = @openingUnits, DivPrice = @divPrice, DivFactor = @divFactor, DRIP = @drip, EndingUnits = @openingUnits + @drip
INTO #Temp

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

WHILE @@FETCH_STATUS = 0
BEGIN

SET @openingUnits = @endingUnits
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

INSERT INTO #Temp (FiscalPeriod, OpeningUnits, DivPrice, DivFactor, DRIP, EndingUnits)
VALUES (@fiscalPeriod, @openingUnits, @divPrice, @divFactor, @drip, @endingUnits)

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

END

CLOSE divCursor
DEALLOCATE divCursor

SELECT * FROM #Temp

DROP TABLE #Temp

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Это может быть выполнено внутри представления как CTE.Ниже приведен пример вашего кода с табличной переменной, заменяющей dbo.Pricing, которая показывает выходные данные вашего SQL и CTE.

DECLARE @Pricing TABLE (
    [FiscalPeriod] smalldatetime,
    [SharePrice] DECIMAL(24,13),
    [Rate] DECIMAL(24,13)
)

INSERT INTO @Pricing ([FiscalPeriod],[SharePrice],[Rate]) SELECT '2018-01-01',10.25,0.01
INSERT INTO @Pricing ([FiscalPeriod],[SharePrice],[Rate]) SELECT '2018-04-01',10.50,0.01
INSERT INTO @Pricing ([FiscalPeriod],[SharePrice],[Rate]) SELECT '2018-07-01',10.86,0.01


DECLARE @fiscalPeriod smalldatetime,
        @openingUnits float,
        @divPrice money,
        @divFactor float,
        @drip float,
        @endingUnits float


DECLARE divCursor CURSOR FOR
SELECT [FiscalPeriod]
      ,[SharePrice]
      ,[Rate]
  FROM @Pricing
  ORDER BY FiscalPeriod
OPEN divCursor
FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

    SET @openingUnits = 1
    SET @drip = @openingUnits/@divPrice*@divFactor
    SET @endingUnits = @openingUnits + @drip

    SELECT
            FiscalPeriod = @fiscalPeriod, OpeningUnits = @openingUnits, DivPrice = @divPrice
        ,   DivFactor = @divFactor, DRIP = @drip, EndingUnits = @openingUnits + @drip
    INTO #Temp

    FETCH NEXT FROM divCursor
    INTO @fiscalPeriod, @divPrice, @divFactor

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @openingUnits = @endingUnits
        SET @drip = @openingUnits/@divPrice*@divFactor
        SET @endingUnits = @openingUnits + @drip

        INSERT INTO #Temp (FiscalPeriod, OpeningUnits, DivPrice, DivFactor, DRIP, EndingUnits)
        VALUES (@fiscalPeriod, @openingUnits, @divPrice, @divFactor, @drip, @endingUnits)

        FETCH NEXT FROM divCursor
        INTO @fiscalPeriod, @divPrice, @divFactor
    END

CLOSE divCursor
DEALLOCATE divCursor

SELECT * FROM #Temp

DROP TABLE #Temp;

--CTE VERSION
WITH fp_cte ([FiscalPeriod],[DivPrice],[DivFactor],[Row])
AS (
    SELECT
            [FiscalPeriod]
        ,   [SharePrice] AS [DivPrice]
        ,   [Rate] AS [DivFactor]
        ,   ROW_NUMBER() OVER (ORDER BY [FiscalPeriod] ASC) AS [Row]
    FROM @Pricing
)
,calc_cte ([FiscalPeriod],[OpeningUnits],[DivPrice],[DivFactor],[DRIP],[EndingUnits],[Row]) 
AS  
(  
    SELECT
            [FiscalPeriod]
        ,   CONVERT(DECIMAL(24,13),1) AS [OpeningUnits]
        ,   [DivPrice]
        ,   [DivFactor]
        ,   CONVERT(DECIMAL(24,13),1.0/[DivPrice]*[DivFactor]) AS [DRIP]
        ,   CONVERT(DECIMAL(24,13),1+(1.0/[DivPrice]*[DivFactor])) AS [EndingUnits]
        ,   [Row]
    FROM fp_cte
    WHERE [Row]=1
    UNION ALL
    SELECT
            p2.[FiscalPeriod]
        ,   CONVERT(DECIMAL(24,13),p1.[EndingUnits]) AS [OpeningUnits]
        ,   p2.[DivPrice]
        ,   p2.[DivFactor]
        ,   CONVERT(DECIMAL(24,13),p1.[EndingUnits]/p2.[DivPrice]*p2.[DivFactor]) AS [DRIP]
        ,   CONVERT(DECIMAL(24,13),p1.[EndingUnits]+(p1.[EndingUnits]/p2.[DivPrice]*p2.[DivFactor])) AS [EndingUnits]
        ,   p2.[Row]
    FROM calc_cte p1
    INNER JOIN fp_cte p2 ON p1.[Row]=(p2.[Row]-1)
)  
SELECT [FiscalPeriod],[OpeningUnits],[DivPrice],[DivFactor],[DRIP],[EndingUnits]
FROM calc_cte;
0 голосов
/ 03 декабря 2018

Вы не можете присоединиться к хранимой процедуре, но вы можете "присоединиться" к скалярной функции с помощью внешнего применения.https://www.sqlshack.com/the-difference-between-cross-apply-and-outer-apply-in-sql-server/

Вы не можете создать временную таблицу в пользовательской функции, но вы можете использовать переменные таблицы.https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/create-user-defined-functions-database-engine?view=sql-server-2017

Кроме этого, я думаю, вы могли бы решить свой сценарий без всего этого.Уилл вернулся позже

...