RAISERROR এর সাথে ফ্ল্যাট ব্যবহার করা


11

আমি RAISERROR()কিছু বেসিক ইউনিট টেস্টিং কার্যকারিতা সরবরাহ করতে ব্যবহার করছি ( এখানে যেমন ) তবে FLOATsত্রুটি বার্তায় ব্যবহার করতে অক্ষম হয়ে আমি হতাশ । আমি জানি আমি একটি স্ট্রিংতে ভাসমানটি কাস্ট করতে পারি, তবে আমি RAISERRORপ্রতিটি ইউনিট পরীক্ষায় ব্যবহার করছি , আমি প্রতিটি পরীক্ষার জন্য কোডের অন্য একটি লাইন যুক্ত করতে চাই না। (আমার ইউনিট পরীক্ষাগুলি ইতিমধ্যে যথেষ্ট শব্দযুক্ত!) প্যারামিটার তালিকার মধ্যে কোনও ইনলাইন কাস্ট / রূপান্তর করার কোনও উপায় আছে কি RAISERROR? নাকি এই ঘাটতি ঘটার অন্য কোনও উপায় আছে?

আপডেট: সুতরাং শেষ পর্যন্ত আমি যা করতে চাই তা হ'ল:

RAISERROR('Unit Test FAILED! %f', 11, 0, @floatParm)

দুর্ভাগ্যক্রমে, RAISERROR% f পরিচালনা করে না বা সাধারণভাবে ভাসমান। সুতরাং এর পরিবর্তে আমাকে এটি করতে হবে:

DECLARE @str VARCHAR(40) = CAST(@floatParm AS VARCHAR(40))
RAISERROR('Unit Test FAILED! %s', 11, 0, @str)

... যা কয়েক ডজন ইউনিট টেস্টের মধ্যে ছড়িয়ে ছিটিয়ে থাকলে তা কেবল গোলমালের মতো দেখায়। সুতরাং আমি এটিকে এই জাতীয় কিছুতে সিদ্ধ করতে চাই:

RAISERROR('Unit Test FAILED! %s', 11, 0, CAST(@floatParm AS VARCHAR(40))

কিন্তু এটি আমার একটি Incorrect syntax near 'CAST'বার্তা পায় । আমি বুঝতে পারি না কেন এটি অবৈধ, তবে এটি। আমি এখানে পরিবর্তে অন্য একটি "ওয়ান লাইনার" ব্যবহার করতে পারি?


আপনি আরও ব্যাখ্যা করতে পারেন দয়া করে?
NoChance

উত্তর:


12

দুর্ভাগ্যক্রমে, যে কারণেই হোক না কেন, আপনি সেই প্রসঙ্গে একটি ইনলাইন রূপান্তর করতে পারবেন না এবং যে কোনও কারণেই RAISERRORসরাসরি floatআবার সমর্থন করবেন না।

এই উত্তরের সম্পূর্ণতার জন্য, এখানে এমএসডিএন থেকে প্রাসঙ্গিক স্নিপেট রয়েছে , যা আমি নিশ্চিত যে আপনি ইতিমধ্যে দেখেছেন (দ্রষ্টব্য: 2005 থেকে 2012 পর্যন্ত ডকুমেন্টেশনের সমস্ত সংস্করণে এটি একই পাঠ্য):

: প্রতিটি প্রতিকল্পন পরামিতি একটি স্থানীয় পরিবর্তনশীল বা কোনো এই তথ্য ধরনের হতে পারে tinyint , smallint , int- এ , গৃহস্থালির কাজ , varchar , nchar , nvarchar , বাইনারি , অথবা varbinary


আমি কেবল যুক্তিসঙ্গত সমাধানের কথা ভাবতে পারি তা হল RAISERRORকলটি মোড়ানোর জন্য একটি সঞ্চিত প্রক্রিয়া লিখতে । এখানে একটি সূচনা পয়েন্ট:

CREATE PROCEDURE [dbo].[MyRaiserror]
(
    @message nvarchar(2048),
    @severity tinyint,
    @state tinyint,
    @arg0 sql_variant = NULL
)
AS
BEGIN

    DECLARE @msg nvarchar(MAX) = REPLACE(@message, '%f', '%s');
    DECLARE @sql nvarchar(MAX) = N'RAISERROR(@msg, @severity, @state';

    DECLARE @int0 int, @char0 nvarchar(MAX), @bin0 varbinary(MAX);

    IF (@arg0 IS NOT NULL)
    BEGIN
        SET @sql += N', ';

        IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('tinyint', 'smallint', 'int'))
        BEGIN
            SET @int0 = CONVERT(int, @arg0);
            SET @sql += N'@int0';
        END
        ELSE IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('binary', 'varbinary'))
        BEGIN
            SET @bin0 = CONVERT(varbinary(MAX), @arg0);
            SET @sql += N'@bin0';
        END
        ELSE
        BEGIN
            SET @char0 = CONVERT(nvarchar(MAX), @arg0);
            SET @sql += N'@char0';
        END
    END

    SET @sql += N');';

    EXEC sp_executesql
        @sql,
        N'@msg nvarchar(2048), @severity tinyint, @state tinyint, @int0 int, @bin0 varbinary(MAX), @char0 nvarchar(MAX)',
        @msg, @severity, @state, @int0, @bin0, @char0;

END

দুঃখের বিষয়, একটি নির্বিচার সংখ্যক পরামিতিগুলির জন্য এটি স্কেল করার সহজ কোনও উপায় নেই ... এটি সম্ভবত সংশ্লেষিত নেস্টেড ডায়নামিক এসকিউএল ব্যবহার করে করা যেতে পারে, যা ডিবাগ করার জন্য মজাদার। আমি পাঠকের জন্য অনুশীলন হিসাবে ছেড়ে দেব।

আমি ব্যবহৃত sql_variantএমনকি যে মান ধরনের জন্য, ধৃষ্টতা যে কোড একরূপতা কারণে একই পদ্ধতি সর্বত্র ব্যবহার করা হবে উপর হয় সরাসরি দ্বারা সমর্থিত RAISERROR। এছাড়াও, এটি উপযুক্ত হলে এটি একটি অস্থায়ী সঞ্চিত প্রক্রিয়া হিসাবে তৈরি করা যেতে পারে ।

এই পদ্ধতিটি ব্যবহার করে দেখতে কেমন হবে তা এখানে:

DECLARE @f float = 0.02345;
DECLARE @i int = 234;
DECLARE @s varchar(20) = 'asdfasdf';
DECLARE @b binary(4) = 0xA0B1C2D3;
DECLARE @d decimal(18, 9) = 152.2323;
DECLARE @n int = NULL;

EXEC [dbo].[MyRaiserror] N'Error message with no params.', 10, 1;
EXEC [dbo].[MyRaiserror] N'Float value = %f', 10, 1, @f;
EXEC [dbo].[MyRaiserror] N'Int value = %i', 10, 1, @i;
EXEC [dbo].[MyRaiserror] N'Character value = %s', 10, 1, @s;
EXEC [dbo].[MyRaiserror] N'Binary value = %#x', 10, 1, @b;
EXEC [dbo].[MyRaiserror] N'Decimal value = %f', 10, 1, @d;
EXEC [dbo].[MyRaiserror] N'Null value = %i', 10, 1, @n;

আউটপুট:

Error message with no params.
Float value = 0.02345
Int value = 234
Character value = asdfasdf
Binary value = 0xa0b1c2d3
Decimal value = 152.232300000
Null value = (null)

সুতরাং নেট ফলাফলটি হ'ল আপনি ভাসমানগুলির জন্য বিন্যাসকরণ ক্ষমতা পাবেন না (নিজের রোল করুন), তবে অন্য ধরণের বিন্যাসকরণ ক্ষমতা ধরে রেখে আপনি সেগুলি (দশমিক / সংখ্যাসূচকও!) আউটপুট দেওয়ার ক্ষমতা অর্জন করতে পারেন।


বাহ, এটি কেবল দুর্দান্ত! আমি এই জাতীয় কিছু করার কথা বিবেচনা করেছি, তবে অবহিত ছিলাম sql_variant, তাই আমি যুক্তি তালিকায় আটকে গিয়েছিলাম এবং ধরে নিয়েছিলাম এটি সম্ভব নয়। আপনি আমাকে আজ খুব দরকারী কিছু শিখিয়েছেন। আপনাকে অনেক ধন্যবাদ!
কিমিওট

@ কেমোট: সমস্যা নেই; আমি সাহায্য করতে পেরে আনন্দিত.
জন সেগেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.