সমান্তরাল এক্সিকিউশন-এখনও সিরিয়াল মোডে চলার জন্য একটি স্কেলার ফাংশনকে একটি টিভিএফ ফাংশনে রূপান্তরিত করে


10

আমার জিজ্ঞাসার মধ্যে একটি রিলিজের পরে সিরিয়াল এক্সিকিউশন মোডে চলছিল এবং আমি লক্ষ্য করেছি যে অ্যাপ্লিকেশন থেকে উত্পন্ন এসকিউএল কোয়েরিতে লিনকিউতে রেফারেন্স করা একটি দৃশ্যে দুটি নতুন ফাংশন ব্যবহৃত হয়েছিল। সুতরাং আমি সেই SCALAR ফাংশনগুলিকে টিভিএফ ফাংশনে রূপান্তর করেছি, তবুও কোয়েরিটি সিরিয়াল মোডে চলছে।

এর আগে আমি স্ক্যালারটিকে টিভিএফ রূপান্তর করতে অন্য কয়েকটি প্রশ্নের মধ্যে করেছি এবং এটি জোর করে সিরিয়াল কার্যকর করার সমস্যাটি সমাধান করেছে solved

এখানে স্কেলার ফাংশনটি রয়েছে:

CREATE FUNCTION [dbo].[FindEventReviewDueDate]
(
       @EventNumber VARCHAR(20),
       @EventID VARCHAR(25),
          @EventIDDate BIT
)

RETURNS DateTime
AS
BEGIN

DECLARE @CurrentEventStatus VARCHAR(20)
DECLARE @EventDateTime DateTime
DECLARE @ReviewDueDate DateTime


SELECT @CurrentEventStatus = (SELECT cis.EventStatus
                                 FROM CurrentEventStatus cis 
                                 INNER JOIN Event1 r WITH (NOLOCK) ON (cis.Event1Id = r.Id)
                                 WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)

SELECT @EventDateTime = (SELECT EventDateTime FROM Event1 r 
                          WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)

IF @CurrentEventStatus IN ('0','6') AND EventIDDate = 1
BEGIN

       SET @ReviewDueDate = DATEADD(DAY, 30, @EventDateTime)

       WHILE @ReviewDueDate < getdate() 
             SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)

       DECLARE @EventDateJournalDate DateTime

       SELECT @EventDateJournalDate = (SELECT TOP 1 ij.Date
                                       FROM EventPage_EventJournal ij 
                                       INNER JOIN EventJournalPages p ON ij.PageId = p.Id 
                                       INNER JOIN Journal f ON p.FormId = f.Id 
                                       INNER JOIN Event1 r WITH (NOLOCK) ON (f.Event1Id = r.Id)
                                       WHERE (r.EventNumber = @EventNumber AND r.EventID = @EventID) AND ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC)

      IF(DATEADD(DAY, 30, @EventDateTime) < getdate() AND
           (@EventDateJournalDate is null OR DATEADD(DAY, 30, @EventDateJournalDate) < getdate()) AND
              DATEADD(DAY, 14, @ReviewDueDate) > DATEADD(DAY, 30, getdate()))
                  SET @ReviewDueDate = DATEADD(DAY, -30, @ReviewDueDate)
         ELSE IF((@EventDateJournalDate is not null ) AND (DATEADD(DAY, 30, @EventDateJournalDate) >= @ReviewDueDate))
                  SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)

END
RETURN @ReviewDueDate

END

রূপান্তরিত টিভিএফ ফাংশনটি এখানে।

CREATE FUNCTION [dbo].[FindEventReviewDueDate_test]
(
       @EventNumber VARCHAR(20),
       @EventID VARCHAR(25),
          @EventIDDate BIT
)

RETURNS @FunctionResultTableVairable TABLE (
 CurrentEventStatus varchar(20),
 Event1DateTime DateTime,
 ReviewDueDate DateTime
 )
AS 
BEGIN

DECLARE @CurrentEventStatus VARCHAR(20)
DECLARE @EventDateTime DateTime
DECLARE @ReviewDueDate DateTime


SELECT @CurrentEventStatus = (SELECT cis.EventStatus
                                 FROM CurrentEventStatus cis 
                                 INNER JOIN Event1 r WITH (NOLOCK) ON (cis.Event1Id = r.Id)
                                 WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)

SELECT @EventDateTime = (SELECT EventDateTime FROM Event1 r 
                          WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)

IF @CurrentEventStatus IN ('0','6') AND EventIDDate = 1
BEGIN

       SET @ReviewDueDate = DATEADD(DAY, 30, @EventDateTime)

       WHILE @ReviewDueDate < getdate() 
             SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)

       DECLARE @EventDateJournalDate DateTime

       SELECT @EventDateJournalDate = (SELECT TOP 1 ij.Date
                                       FROM EventPage_EventJournal ij 
                                       INNER JOIN EventJournalPages p ON ij.PageId = p.Id 
                                       INNER JOIN Journal f ON p.FormId = f.Id 
                                       INNER JOIN Event1 r WITH (NOLOCK) ON (f.Event1Id = r.Id)
                                       WHERE (r.EventNumber = @EventNumber AND r.EventID = @EventID) AND ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC)

      IF(DATEADD(DAY, 30, @EventDateTime) < getdate() AND
           (@EventDateJournalDate is null OR DATEADD(DAY, 30, @EventDateJournalDate) < getdate()) AND
              DATEADD(DAY, 14, @ReviewDueDate) > DATEADD(DAY, 30, getdate()))
                  SET @ReviewDueDate = DATEADD(DAY, -30, @ReviewDueDate)
         ELSE IF((@EventDateJournalDate is not null ) AND (DATEADD(DAY, 30, @EventDateJournalDate) >= @ReviewDueDate))
                  SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
                   insert into @FunctionResultTableVairable
      select @CurrentEventStatus,@EventDateTime,@ReviewDueDate          

END
return;
END

GO

আমার TVF ফাংশন বাস্তবায়নে কোন সমস্যা আছে যা কোয়েরিকে সমান্তরাল মোডে চালাতে বাধা দিচ্ছে?

আমি নীচে হিসাবে কোয়েরিতে টিভিএফ ফাংশনটি ব্যবহার করি;

select ReviewDueDate from dbo.FunctionResultTableVairable('a','b','c')

আমার আসল জিজ্ঞাসাটি যা ভিউটি ব্যবহার করে তা বেশ জটিল এবং আমি যদি ভিউ এবং ক্রিয়াকলাপটির অংশটি মন্তব্য করি তবে কোয়েরিটি সমান্তরালে চলে o সুতরাং এটি এমন ফাংশন যা কোয়েরিকে সমান্তরালে চালাতে বাধ্য করছে।

আমার আসল জিজ্ঞাসাটি নীচের বিন্যাসে।

select 
dv.column1,
dv.column2,
---------
---------
--------
(select ReviewDueDate from dbo.FunctionResultTableVairable('a','b','c')) AS 'Columnx'
from
DemoView dv
Where 
condition1
conditon 2

কোন সাহায্য প্রশংসা করা হয়।


3
ক্যোয়ারী প্ল্যান কী বলে?
ডেভিড ব্রাউন - মাইক্রোসফ্ট

2
ইন-লাইন টিভিএফ এবং মাল্টি-স্টেটমেন্ট টিভিএফের মধ্যে বড় পার্থক্য ছাড়াও, যদি আপনার টিভিএফ যদি বাইরের ক্যোয়ারিতে প্রতিটি সারির জন্য একই সারিটি ফেরত দেয় (যেহেতু এটি কেবল ধ্রুবক লাগে) এবং আপনি কেবল একটি আউটপুট কলামের যত্ন নেন , আপনি কেন এটি বাছাই তালিকায় সাবকিউরিতে রাখছেন? এটি কেবল অকারণে বারবার চালানো সম্ভব করে তোলে। কোনও চলককে আউটপুট বরাদ্দ করুন এবং তারপরে আপনার ক্যোয়ারিতে ভেরিয়েবলটি ব্যবহার করুন।
অ্যারন বারট্র্যান্ড

উত্তর:


5

আমার স্কেলারের ফাংশনটি ইনলাইন টিভিএফে রূপান্তর করা কি সম্ভব?

হ্যাঁ. নীচের মতো কিছু এটি করবে।

এটি এখনও বেশ মোটা এবং এটি যদি সম্পর্কযুক্ত হয় তবে এটি সম্ভবত যথেষ্ট অদক্ষ। হারুন মন্তব্যে উল্লেখ করার সাথে সাথে আপনি এটিকে ধ্রুব মান সহ কল ​​করছেন যদিও আশা করি ক্যোয়ারী পরিকল্পনাটি এটি প্রতিফলিত করে এবং কেবল একবার এটি চালায়।

CREATE FUNCTION [dbo].[FindEventReviewDueDateInline] (@EventNumber VARCHAR(20),
                                                      @EventID     VARCHAR(25),
                                                      @EventIDDate BIT)
RETURNS TABLE
AS
    RETURN
      WITH X
           AS (SELECT cis.EventStatus AS CurrentEventStatus,
                      r.EventDateTime
               FROM   CurrentEventStatus cis
                      INNER JOIN Event1 r
                              ON cis.Event1Id = r.Id
               WHERE  r.EventNumber = @EventNumber
                      AND r.EventID = @EventID
                      AND cis.EventStatus IN ( '0', '6' )
                      AND @EventIDDate = 1)
      SELECT X.CurrentEventStatus,
             X.EventDateTime,
             CA4.ReviewDueDate
      FROM   X
             --SET @ReviewDueDate = DATEADD(DAY, 30, @EventDateTime)
             CROSS APPLY(VALUES(DATEADD(DAY, 30, X.EventDateTime))) CA1(ReviewDueDate)
             -- WHILE @ReviewDueDate < getdate() 
             --       SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
             CROSS APPLY(VALUES( IIF(CA1.ReviewDueDate >= GETDATE(), CA1.ReviewDueDate, DATEADD(DAY, 30 * CEILING(( IIF(CAST(GETDATE() AS TIME) > CAST(CA1.ReviewDueDate AS TIME), 1, 0)
                                                                                                           + DATEDIFF(DAY, CA1.ReviewDueDate, GETDATE()) ) / 30.0), CA1.ReviewDueDate)))) CA2(ReviewDueDate)
             --SELECT @EventDateJournalDate = ....
             CROSS APPLY(SELECT TOP 1 ij.Date
                         FROM   EventPage_EventJournal ij
                                INNER JOIN EventJournalPages p
                                        ON ij.PageId = p.Id
                                INNER JOIN Journal f
                                        ON p.FormId = f.Id
                                INNER JOIN Event1 r WITH (NOLOCK)
                                        ON ( f.Event1Id = r.Id )
                         WHERE  ( r.EventNumber = @EventNumber
                                  AND r.EventID = @EventID )
                                AND ij.ReviewType = 'Supervisor Monthly Review'
                         ORDER  BY ij.Date DESC) CA3(EventDateJournalDate)
             -- IF(DATEADD(DAY, 30, @EventDateTime) < getdate()
             CROSS APPLY(VALUES ( CASE
                          WHEN ( DATEADD(DAY, 30, X.EventDateTime) < GETDATE()
                                 AND ( CA3.EventDateJournalDate IS NULL
                                        OR DATEADD(DAY, 30, CA3.EventDateJournalDate) < GETDATE() )
                                 AND DATEADD(DAY, 14, CA2.ReviewDueDate) > DATEADD(DAY, 30, GETDATE()) )
                            THEN DATEADD(DAY, -30, CA2.ReviewDueDate)
                          WHEN( ( CA3.EventDateJournalDate IS NOT NULL )
                                AND ( DATEADD(DAY, 30, CA3.EventDateJournalDate) >= CA2.ReviewDueDate ) )
                            THEN DATEADD(DAY, 30, CA2.ReviewDueDate)
                          ELSE CA2.ReviewDueDate
                        END )) CA4(ReviewDueDate); 

11

ফরেস্ট বেশিরভাগ ক্ষেত্রে সঠিক, তবে সূক্ষ্ম বিবরণগুলি হ'ল :

এসকিউএল সার্ভার আপনার ফাংশনটি ব্যবহার করে, টেবিল ভেরিয়েবলগুলির পরিবর্তনগুলিকে সমান্তরাল করতে পারে না।

এসকিউএল সার্ভার 2017 এর আন্তঃবাহিত সম্পাদনের আগে , মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান কার্যাদি থেকে সারি অনুমান খুব কম ছিল।

এর একটি পার্শ্ব প্রতিক্রিয়া হ'ল পরিকল্পনাগুলি নিম্ন প্রান্তে খুব খারাপভাবে তৈরি হয়েছিল এবং প্রায়শই সমান্তরালতার জন্য ব্যয়ের প্রান্তিকতা ভাঙবে না।


1
OkayCan আপনি যে কোনও বিকল্প সমাধানকে মিলেছেন যাতে আমার মূল ক্যোয়ারীটি সমান্তরাল মোডে চলতে পারে my আমার স্কেলারার ফানসিটনের দিকে তাকিয়ে কি আমার স্কেলার ফাংশনটি ইনলাইন টিভিএফে রূপান্তর করা সম্ভব?
ব্যবহারকারী 9516827

1
@ ব্যবহারকারী 9516827 আপনি সম্ভবত কিছু সিটিইগুলিকে একসাথে চেইন করতে পারতেন অনুরূপ কিছু করার জন্য, তবে এটি সমান্তরাল হয়ে উঠবে কিনা, আরও ভাল পারফরম্যান্স করবে কিনা আমার ধারণা নেই, এটি পরীক্ষা করে নেওয়া আপনার উপর নির্ভর করে।
এরিক ডার্লিং

@ মার্টিনস্মিত: আমার আসল জিজ্ঞাসাটি একটি অত্যন্ত জটিল ক্যোয়ারী যা প্রচুর যোগদান এবং দর্শনের সাথে যোগ দেয় etc. এই ফাংশনটি মূল কোয়েরিতে একটি নির্বাচিত কলামের জন্য ব্যবহৃত হয় এবং সে কারণেই আমি সেই স্থির করার চেষ্টা করছিলাম A এছাড়াও এটি একটি লিনকিউ -এসকিউএল (এক্সিকিউটিভ এসপি_এক্সেকটসকিউএল ফর্ম) উত্পন্ন ক্যোয়ারী তৈরি করেছে এবং আমার কাছে। নেট কোড হ্যাক না করার সীমাবদ্ধতা রয়েছে
ধন্যবাদ

10

এসকিউএল সার্ভার মাল্টি স্টেটমেন্ট টিভিএফগুলির সমান্তরাল করতে পারে না, যা আপনার yours কেবল ইনলাইন টিভিএফগুলিকেই সমান্তরাল করা যায়।


1
যেহেতু আমার সেখানে ভেরিয়েবল রয়েছে তাই আমি স্কেলারের ফাংশনটি ইনলাইন টিভিএফ এ রূপান্তর করতে পারছি না?
ব্যবহারকারী 9516827
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.