ফর্ম্যাট () একটি ননডেটেরিমেন্টিক অন্তর্নির্মিত স্ট্রিং ফাংশন… ঠিক?


10

আমি এই সম্পর্কে ডকুমেন্টেশনের অভাবে কোনও সংযোগ আইটেম পোস্ট করার আগে কেউ কি নিশ্চিত করবে যে আমি এখানে কিছু মিস করছি না?

দস্তাবেজ পৃষ্ঠায় যেখানে formatস্ট্রিং ফাংশন হিসাবে তালিকাবদ্ধ রয়েছে:

"সমস্ত অন্তর্নির্মিত স্ট্রিং ফাংশনগুলি হ'ল ডিস্ট্রিমেন্টিক" " - স্ট্রিং ফাংশন (লেনদেন-এসকিউএল)

formatসম্পর্কিত পৃষ্ঠাগুলিতে নিরপেক্ষবাদী হওয়ারও উল্লেখ নেই :


যাইহোক, একটি স্থির গণিত কলাম তৈরি করার চেষ্টা করার সময়:

create table t (date_col date); 
insert into t values (getdate());
alter table t add date_formatted_01 as format(date_col,'YYYY') persisted;

নিম্নলিখিত ত্রুটি প্রদান করে:

টেবিল 't' তে গণনা করা কলাম 'তারিখ_ফর্মেটেড_01' ধরে রাখা যায় না কারণ কলামটি অ-সংঘবদ্ধ।

ডকুমেন্টেশন বলে যে

যদি সংস্কৃতি যুক্তি সরবরাহ না করা হয় তবে বর্তমান অধিবেশনটির ভাষা ব্যবহৃত হয়।

কিন্তু সংস্কৃতি যুক্তি যুক্ত করা জিনিস পরিবর্তন করে না

এটিও ব্যর্থ হয়

alter table t add date_formatted_02 as format(date_col, 'd', 'en-US' ) persisted

রেক্সটেস্টার ডেমো: http://rextester.com/ZMS22966

dbfiddle.uk ডেমো: http://dbfiddle.uk/?rdbms=sqlserver_next&fiddle=7fc57d1916e901cb561b551af144aed6


1
এটাও ব্যর্থ হলে: alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;। নিশ্চিত নন কেন সংবেদনশীল FORMATনয়, বিশেষত সংস্কৃতি নির্দিষ্ট করার সময়। date_formattedকলাম করতে হবে VARCHAR(20)(এখনও স্থায়ী) এবং ব্যবহার ট্রিগার মাধ্যমে নির্ধারণ করে FORMAT। অথবা এসকিউএলসিএলআর কাজ করে। এসকিউএল # এসকিউএলসিএলআর লাইব্রেরি ব্যবহার করে (যা আমি লিখেছি) আপনি করতে পারেন ALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;(টেবিলটি এসকিউএল # এর মালিকানাযুক্ত, যেহেতু টেবিল এবং ফাংশন মালিক একই হওয়া দরকার)।
সলোমন রুটজকি

উত্তর:


5

একটি ফাংশন অগত্যা নিরস্তক বা ননডেটেরিমেন্টিক নয়। কিছু ফাংশন রয়েছে যা সেগুলি কীভাবে ব্যবহৃত হয় তার উপর নির্ভর করে নির্দোষ হতে পারে :

নিম্নলিখিত ফাংশনগুলি সর্বদা নিরঙ্কুশায়ী হয় না, তবে তারা যখন নির্বিচারক পদ্ধতিতে নির্দিষ্ট করা হয় তখন গণিত কলামগুলিতে সূচী দর্শন বা সূচীতে ব্যবহার করা যেতে পারে।

CASTএবং CONVERTযেমন উদাহরণ। আপনি এখনও অবধি যে পরীক্ষার কাজটি করেছেন তার উপর ভিত্তি করে, আমি মনে করি যে এটি FORMATস্ট্রিং ফাংশন সত্ত্বেও সর্বদা নির্দোষ নয়, তা বলা উচিত say যদি আপনি জানতে চান যে এটি কখনও কখনও নির্বিচারে একমাত্র কৌশল যা আমি ভাবতে পারি তা হ'ল আপনি সন্তুষ্ট না হওয়া পর্যন্ত এটিকে কল করার জন্য যথেষ্ট আলাদা উপায় চেষ্টা করা। উদাহরণস্বরূপ, আসুন FORMATসংখ্যা হিসাবে প্রয়োগ হিসাবে বিবেচনা করা যাক । কেবলমাত্র দশটি পৃথক সংখ্যার ইনপুট প্রকার রয়েছে :

সংখ্যার ইনপুট প্রকার

এছাড়াও কেবল নয়টি পৃথক সংখ্যার ফর্ম্যাট উপস্থিত রয়েছে । সমস্ত সম্ভাব্য সংমিশ্রণের জন্য স্থায়ী কলাম তৈরি করার চেষ্টা করা সম্ভব। এটি করার জন্য কিছু কোড নীচে রয়েছে:

DECLARE @FormatValue INT = 76767; -- change this if you want
DECLARE @FormatCulture VARCHAR(10) = 'en-US'; -- change this if you want
DECLARE @Format VARCHAR(1);
DECLARE @FormatType VARCHAR(10);
DECLARE @SQLForColumn VARCHAR(200);
DECLARE @TestNumber INT = 0;

BEGIN

    DROP TABLE IF EXISTS dbo.TargetTable;
    CREATE TABLE dbo.TargetTable (ID INT);

    DROP TABLE IF EXISTS #ColumnAddResults;
    CREATE TABLE #ColumnAddResults (
    FormatType VARCHAR(10),
    [Format] VARCHAR(1), 
    Succeeded VARCHAR(1), 
    ErrorMessage VARCHAR(1000)
    );

    drop table if exists #Types;
    create table #Types (FormatType VARCHAR(10));

    INSERT INTO #Types VALUES
    ('bigint'), ('int'), ('smallint'), ('tinyint'), ('decimal')
    , ('numeric'), ('float'), ('real'), ('smallmoney'), ('money');

    drop table if exists #Formats;
    create table #Formats ([Format] VARCHAR(1));

    INSERT INTO #Formats VALUES 
    ('C'), ('D'), ('E'), ('F'), ('G'), ('N'), ('P'), ('R'), ('X');

    DECLARE format_statements CURSOR LOCAL FAST_FORWARD FOR 
    SELECT #Types.FormatType, #Formats.[Format]
    FROM #Formats
    CROSS JOIN #Types;

    OPEN format_statements;

    FETCH NEXT FROM format_statements   
    INTO @FormatType, @Format;  

    WHILE @@FETCH_STATUS = 0  
    BEGIN
        SET @TestNumber = @TestNumber + 1;
        SET @SQLForColumn = 'alter table dbo.TargetTable add NewColumn' + CAST(@TestNumber AS VARCHAR(10))
        + ' as FORMAT(CAST(' +  CAST(@FormatValue AS VARCHAR(10)) + ' AS ' + @FormatType + '), '
        + '''' + @Format + ''', ''' + @FormatCulture + ''') persisted';

        BEGIN TRY
            EXEC (@SQLForColumn);
            INSERT INTO #ColumnAddResults VALUES (@FormatType, @Format, 'Y', NULL);
        END TRY
        BEGIN CATCH
            INSERT INTO #ColumnAddResults VALUES (@FormatType, @Format, 'N', ERROR_MESSAGE());
        END CATCH;

        PRINT @SQLForColumn;

        FETCH NEXT FROM format_statements   
        INTO @FormatType, @Format;  
    END;

    CLOSE format_statements;  
    DEALLOCATE format_statements;  

    SELECT * FROM dbo.TargetTable;
    SELECT * FROM #ColumnAddResults;
    DROP TABLE #ColumnAddResults;

END;

এখানে আউটপুট একটি নমুনা:

পরীক্ষার কোড আউটপুট

কয়েকটি ইনপুট মান এবং সংস্কৃতির জন্য আমি কোনও কলাম টেবিলের সাথে যুক্ত করতে পারিনি। আমি নিখুঁতভাবে সমস্ত সম্ভাব্য সংস্কৃতি চেষ্টা করে দেখিনি কারণ এসকিউএল সার্ভারের মধ্যে আমি তাদের একটি তালিকা পাই না।

অন্ততপক্ষে এটি উপসংহারে নিরাপদ বলে মনে হয় যে নির্ধারণের সম্পর্কিত ডকুমেন্টেশনটি FORMATভুল, তাই আমি এটির জন্য একটি সংযুক্ত আইটেম জমা দেওয়ার পরামর্শ দেব।


6

FORMATডকুমেন্টেশন এখন হয়েছে আপডেট (আপনার প্রতিক্রিয়ায় কানেক্ট আইটেমটি বলতে):

FORMATফাংশন nondeterministic হয়।

তেমনি স্ট্রিং ফাংশন (ট্রানজেক্ট-এসকিউএল) এখন অন্তর্ভুক্ত:

সমস্ত অন্তর্নির্মিত স্ট্রিং ফাংশনগুলি FORMATডিটারমিনিস্টিক।


1

আমি স্ক্যালসারভারের নিয়মিত ব্যবহারকারী নই, তাই আমার ভুল হতে পারে, তবে আমার অনুমান যে ফর্ম্যাটটি স্ট্রিং ফাংশন নয়। ডকুমেন্টেশন অনুযায়ী:

https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql

বিন্যাসটি একটি তারিখের টাইপ বা একটি সংখ্যার প্রকারকে আর্গুমেন্ট হিসাবে গ্রহণ করে। আপনি যা করতে চান তা যদি কোনও তারিখের বছরের অংশটি দখল করতে হয় তবে আপনি বছরের ফাংশনটি ব্যবহার করতে পারবেন না?

alter table t 
    add date_formatted_01 as year(date_col) persisted;

আপনি যদি একটি স্ট্রিং প্রতিনিধিত্ব চান:

alter table t 
    add date_formatted_01 as cast(year(date_col) as char(4)) persisted;

1
এটি ডক্সে একটি স্ট্রিং ফাংশন হিসাবে তালিকাভুক্ত। i.stack.imgur.com/aj0T2.png
মার্টিন স্মিথ

1
@ মার্টিনস্মিত, আকর্ষণীয় ব্যক্তিগতভাবে আমি এটিকে স্বজ্ঞাত হিসাবে মনে করি এবং এটি "সমস্ত অন্তর্নির্মিত স্ট্রিং ফাংশনগুলি হ'ল ডিস্ট্রিমেন্টিকের সাথেও যুক্তিযুক্তভাবে বেমানান।"
লেনার্ট

@ লেননার্ট আমি উদাহরণটির বিকল্পটির প্রশংসা করি, তবে উদাহরণটি গুরুত্বপূর্ণ ছিল না।
স্ক্লিজিম ২

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