मैं Synapse में date_dimension बनाने के लिए 2 संग्रहीत कार्यविधियों का उपयोग करता हूं। पहली खरीद एक साल का विवरण बनाने के लिए और दूसरी खरीद एक प्रतिलिपि गतिविधि के माध्यम से वर्षों की एक श्रृंखला बनाने के लिए इसे फिर से शुरू करने के लिए।

दूसरी खरीद में 2 आयात पैरामीटर हैं जैसे कि YearStart=2000 और YearEnd=2030। हालांकि जब मैं प्रतिलिपि गतिविधि निष्पादित करता हूं तो यह केवल केवल एक वर्ष (2000) के लिए दिनांक तालिका बनाता है और ऐसा लगता है कि लूप काम नहीं करता है!

यहाँ दूसरी खरीद है।

CREATE OR ALTER PROCEDURE [PopulateDateDimensionForYearRange] @YearStart [int], @YearEnd [int] 
AS

BEGIN
    DECLARE @CurrentYear INT
    SET @CurrentYear = @YearStart
    WHILE @CurrentYear IS NOT NULL AND @YearStart <= @YearEnd AND @CurrentYear <= @YearEnd
    BEGIN
        EXEC PopulateDateDimensionForYear @Year = @CurrentYear;
        SET @CurrentYear  = @CurrentYear  + 1   
    END;
END;

जैसा कि आप देख सकते हैं कि पहली खरीद का नाम PopulateDateDimensionForYear है जिसे मैं दूसरी खरीद में कहता हूं और यह पूरी तरह से काम करता है। चूंकि उसका विवरण केवल एक वर्ष ही सही है।

CREATE OR ALTER PROCEDURE [PopulateDateDimensionForYear] @Year [int] AS

BEGIN
    IF OBJECT_ID('tempdb..#month', 'U') IS NOT NULL
        DROP TABLE #month
    CREATE TABLE #month (
        monthnum int,
        numofdays int
    )
    INSERT INTO #month
        SELECT 1, 31 UNION SELECT 2, CASE WHEN (@YEAR % 4 = 0 AND @YEAR % 100 <> 0) OR @YEAR % 400 = 0 THEN 29 ELSE 28 END UNION SELECT 3,31 UNION SELECT 4,30 UNION SELECT 5,31 UNION SELECT 6,30 UNION SELECT 7,31 UNION SELECT 8,31 UNION SELECT 9,30 UNION SELECT 10,31 UNION SELECT 11,30 UNION SELECT 12,31

    IF OBJECT_ID('tempdb..#days', 'U') IS NOT NULL
        DROP TABLE #days
    CREATE TABLE #days (days int)

    INSERT INTO #days
        SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION SELECT 20    UNION SELECT 21 UNION SELECT 22 UNION SELECT 23 UNION SELECT 24 UNION SELECT 25 UNION SELECT 26 UNION SELECT 27 UNION SELECT 28 UNION SELECT 29 UNION SELECT 30 UNION SELECT 31

    SELECT
        CAST(CAST(monthnum AS VARCHAR(2)) + '/' + CAST([days] AS VARCHAR(3)) + '/' + CAST(@year AS CHAR(4)) AS DATE) AS [Date]
        ,DAY(CAST(CAST(monthnum AS VARCHAR(2)) + '/' + CAST([days] AS VARCHAR(3)) + '/' + CAST(@year AS CHAR(4)) AS DATE)) AS [Day]
        ,CAST(DATENAME(month, CAST(CAST(monthnum AS VARCHAR(2)) + '/' + CAST([days] AS VARCHAR(3)) + '/' + CAST(@year as char(4)) AS DATE)) AS nvarchar(10)) AS [MonthName]
        ,MONTH(CAST(CAST(monthnum as varchar(2)) + '/' + CAST([days] as varchar(3)) + '/' + CAST(@year as char(4)) AS DATE)) AS [MonthNumber]
        ,CAST(N'CY' + CAST(YEAR(CAST(CAST(monthnum as varchar(2)) + '/' + CAST([days] as varchar(3)) + '/' + CAST(@year as char(4)) AS DATE)) AS nvarchar(4)) + N'-' + SUBSTRING(DATENAME(month, CAST(CAST(monthnum as varchar(2)) + '/' + CAST([days] as varchar(3)) + '/' + CAST(@year as char(4)) AS DATE)), 1, 3) AS nvarchar(10)) AS [CalendarMonthLabel]
        ,YEAR(CAST(CAST(monthnum as varchar(2)) + '/' + CAST([days] as varchar(3)) + '/' + CAST(@year as char(4)) AS DATE)) AS [Year]
        , DATEPART(ISO_WEEK, CAST(CAST(monthnum as varchar(2)) + '/' + CAST([days] as varchar(3)) + '/' + CAST(@year as char(4)) AS DATE)) AS [ISOWeekNumber]
FROM #month m
    CROSS JOIN #days d
WHERE d.days <= m.numofdays

DROP table #month;
DROP table #days;
END;

क्या कोई जानता है कि इसे सीमा में सभी वर्षों के लिए कैसे किया जाए?

enter image description here

enter image description here

2
Ehsan 25 जून 2021, 11:38

2 जवाब

सबसे बढ़िया उत्तर

अंत में मुझे @ wBob के उत्तर से एक विचार आया। मैंने इसे नीचे रखा।

मूल रूप से मुझे जो चाहिए था वह यह था कि दूसरी खरीद को निम्नानुसार संशोधित किया जाए:

CREATE OR ALTER PROCEDURE [PopulateDateDimensionForYearRange] @YearStart [int], @YearEnd [int] AS

BEGIN
    IF OBJECT_ID('tempdb..#date_dimension', 'U') IS NOT NULL
        DROP TABLE #date_dimension
    CREATE TABLE #date_dimension (
        Date Date,
        Day int,
        MonthName VARCHAR(30),
        MonthNumber int,
        CalendarMonthLabel VARCHAR(30),
        Year int,
        ISOWeekNumber int
    )

    DECLARE @CurrentYear INT
    SET @CurrentYear = @YearStart
    WHILE @CurrentYear IS NOT NULL AND @YearStart <= @YearEnd AND @CurrentYear <= @YearEnd
    BEGIN
        INSERT INTO #date_dimension EXEC PopulateDateDimensionForYear @Year = @CurrentYear;
        SET @CurrentYear  = @CurrentYear  + 1   
    END;
    SELECT * FROM #date_dimension 
    DROP TABLE #date_dimension
END;

बाकी पूरी तरह से पहले जैसा ही है, मेरी कॉपी गतिविधि में!

1
Ehsan 25 जून 2021, 15:58

आपकी दूसरी खरीद कई परिणाम लौटाती है इसलिए कॉपी गतिविधि के साथ काम नहीं करेगी। आपके पास कुछ विकल्प हैं: 1) अपनी दूसरी खरीद को SELECT INTO एक अस्थायी तालिका में बदलें, और फिर INSERT को अपने मुख्य दिनांक आयाम में बदलें और इसे संग्रहीत प्रक्रिया गतिविधि के साथ कॉल करें:

    SELECT
        ...
INTO #tmp
FROM #month m
    CROSS JOIN #days d
WHERE d.days <= m.numofdays


INSERT yourDateDim
SELECT * FROM #tmp

या अपने वर्षों को उत्पन्न करने के लिए 'श्रेणी' फ़ंक्शन के साथ प्रत्येक लूप के लिए उपयोग करने के लिए अपनी प्रक्रिया बदलें:

@range(2000,30)

enter image description here

Azure Synapse INSERT ... EXEC का समर्थन नहीं करता है, लेकिन यहां

2
wBob 25 जून 2021, 10:11