বামদিকে একটি নির্দিষ্ট দৈর্ঘ্যে কোনও ভার্চার প্যাড করার সর্বাধিক দক্ষ টি-এসকিউএল উপায়?


205

হিসাবে তুলনায়:

REPLICATE(@padchar, @len - LEN(@str)) + @str

আমি শেষ সম্পাদনাটি ঘুরিয়েছি। প্রশ্নটি একটি উপায় দেয় - আমি আরও সর্বোত্তম উপায়ের সন্ধান করছিলাম। সম্পাদনাটি অন্য কোনও মানের সন্ধানে এই প্রভাবটি হারিয়েছে।
ক্যাড রক্স

উত্তর:


323

এটি সহজভাবে এসকিউএল এর অদক্ষ ব্যবহার, আপনি এটি কীভাবেই করেন না কেন।

সম্ভবত কিছু

right('XXXXXXXXXXXX'+ rtrim(@str), @n)

যেখানে এক্স আপনার প্যাডিং চরিত্র এবং @n হ'ল ফলাফলের স্ট্রিংয়ের অক্ষরের সংখ্যা (ধরে নিলে আপনার প্যাডিং দরকার কারণ আপনি একটি নির্দিষ্ট দৈর্ঘ্যের সাথে ডিল করছেন)।

তবে আমি যেমন বলেছি আপনার ডাটাবেসে আপনার সত্যই এড়ানো উচিত।


2
এমন সময় আছে যেখানে এটি প্রয়োজন ... উদাহরণস্বরূপ, পেজযুক্ত স্ক্রিনের জন্য ডেটার একটি উপসেট আনা।
বীপ বীপ

7
+1 সবেমাত্র বিভিন্ন পদ্ধতির লোড পরীক্ষা করেছে এবং এটি ছিল দ্রুততম। RTRIM(@str)আপনার এটির পিছনে স্থান থাকতে পারে কিনা তা প্রয়োজন হতে পারে।
মার্টিন স্মিথ

1
+1 কেন আমার চর (6) সঠিকভাবে প্যাড করছে না তা নিয়ে ভাবছিলাম এবং আরটিআরআইএম ইনপুট ভেরিয়েবল আমাকে কিছু মাথা
চুলকানো

@ মার্টিনস্মিত আপনাকে ধন্যবাদ ... আমি কেন আমার স্ট্রিংটি কাজ করছে না এবং তা নির্ধারণ করার চেষ্টা করেছি। TY।
ওয়ার্নার সিডি

3
এটি একটি দুর্দান্ত উত্তর। অবশ্যই যখন আপনার প্রয়োজন হবে না তখন আপনার এটি করা এড়ানো উচিত, তবে কখনও কখনও এটি অনিবার্য নয়; আমার ক্ষেত্রে স্থাপনার সীমাবদ্ধতার কারণে আমার কাছে সি # তে করার পছন্দ নেই, এবং শীর্ষস্থানীয় শূন্যগুলির সাথে 5 টি বর্ণের সংখ্যার স্ট্রিং হওয়া উচিত ছিল এমন কেউ আইএনটি হিসাবে একটি ফ্র্যাঞ্চাইজি নম্বর সংরক্ষণ করেছিল stored এটি প্রচুর সাহায্য করেছিল।
জিম

57

আমি জানি এটি মূলত ২০০৮ সালে ফিরে জিজ্ঞাসা করা হয়েছিল, তবে এসকিউএল সার্ভার ২০১২ এর সাথে এমন কিছু নতুন ফাংশন প্রবর্তিত হয়েছিল। ফর্ম্যাট ফাংশনটি জিরো সহ সুন্দরভাবে বাম প্যাডিংকে সহজতর করে। এটি আপনার জন্য রূপান্তরও সম্পাদন করবে:

declare @n as int = 2
select FORMAT(@n, 'd10') as padWithZeros

হালনাগাদ:

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

SET STATISTICS TIME ON
select FORMAT(N, 'd10') as padWithZeros from Tally
SET STATISTICS TIME OFF

এসকিউএল সার্ভার এক্সিকিউশন টাইমস: সিপিইউ সময় = 2157 এমএস, অতিবাহিত সময় = 2696 এমএস।

SET STATISTICS TIME ON
select right('0000000000'+ rtrim(cast(N as varchar(5))), 10) from Tally
SET STATISTICS TIME OFF

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:

সিপিইউ সময় = 31 এমএস, অতিবাহিত সময় = 235 এমএস।


1
এটি ঠিক আমি যা খুঁজছিলাম ছিল। ফরমেটের
ফের গার্সিয়া

1
এটি এমএসডিএন এবং এসকিউএল সার্ভার ২০১২
arame3333

5
যদিও এটি জিজ্ঞাসা করা হয়েছে "সর্বাধিক দক্ষ" উপায় হবে না। এই উদাহরণে ফর্ম্যাট 180 সেকেন্ড বনাম 12 সেকেন্ড নেয়। stackoverflow.com/a/27447244/73226
মার্টিন স্মিথ

2
প্রোগ্রামারটিকে এটি ব্যবহার করতে সময় লাগার ক্ষেত্রে এটি "সবচেয়ে দক্ষ" হতে পারে!
আন্ডারস্কোর_ড

36

বেশ কয়েকটি লোক এর সংস্করণ দিয়েছে:

right('XXXXXXXXXXXX'+ @str, @n)

এটির সাথে সাবধান থাকুন কারণ এটি যদি আপনার n এর চেয়ে বেশি হয় তবে আপনার প্রকৃত ডেটা কেটে যাবে।


17
@padstr = REPLICATE(@padchar, @len) -- this can be cached, done only once

SELECT RIGHT(@padstr + @str, @len)

9

বোধহয় একটি ওভার কিল আমার বাম এবং ডান প্যাডে এই ইউডিএফ রয়েছে

ALTER   Function [dbo].[fsPadLeft](@var varchar(200),@padChar char(1)='0',@len int)
returns varchar(300)
as
Begin

return replicate(@PadChar,@len-Len(@var))+@var

end

এবং ডান থেকে

ALTER function [dbo].[fsPadRight](@var varchar(200),@padchar char(1)='0', @len int) returns varchar(201) as
Begin

--select @padChar=' ',@len=200,@var='hello'


return  @var+replicate(@PadChar,@len-Len(@var))
end

স্কেলার ইউডিএফগুলির সাথে একমাত্র সমস্যা হ'ল তারা সমতুল্য কোড ইনলাইন (প্লাসে ডেটা টাইপ সমস্যা রয়েছে) এর চেয়ে অনেক খারাপভাবে পারফর্ম করে। আশা করি তারা ভবিষ্যতের সংস্করণে আরও ভাল স্কেলার ইউডিএফ কর্মক্ষমতা এবং / অথবা ইনলাইন স্কেলারার ইউডিএফ প্রবর্তন করবে ing
ক্যাড রক্স

আপনি যদি দৈর্ঘ্যের চেয়ে কম দৈর্ঘ্য নির্দিষ্ট করেন তবে এই ফাংশনগুলি শূন্য হয়। দৈর্ঘ্য কম হলে কেবল পরিবর্তিত আকারে ফিরে আসার জন্য প্রতিটি প্রতিলিপি বিবৃতিকে একটি ইসনুল স্টেটমেন্ট দিয়ে মুড়িয়ে দিন। isnull (প্রতিলিপি (...), '')
জার্সি ডুড

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

7

আমি নিশ্চিত নই যে আপনি যে পদ্ধতিটি দিয়েছেন তা সত্যই অদক্ষ, তবে একটি বিকল্প উপায়, যতক্ষণ না এটি দৈর্ঘ্য বা প্যাডিং চরিত্রের ক্ষেত্রে নমনীয় হতে না পারে, (ধরে নিবেন যে আপনি এটি দিয়ে প্যাড করতে চান " 0 "থেকে 10 টি অক্ষর:

DECLARE
   @pad_characters VARCHAR(10)

SET @pad_characters = '0000000000'

SELECT RIGHT(@pad_characters + @str, 10)

2

সম্ভবত ওভারকিল, আমি প্রায়শই এই ইউডিএফ ব্যবহার করি:

CREATE FUNCTION [dbo].[f_pad_before](@string VARCHAR(255), @desired_length INTEGER, @pad_character CHAR(1))
RETURNS VARCHAR(255) AS  
BEGIN

-- Prefix the required number of spaces to bulk up the string and then replace the spaces with the desired character
 RETURN ltrim(rtrim(
        CASE
          WHEN LEN(@string) < @desired_length
            THEN REPLACE(SPACE(@desired_length - LEN(@string)), ' ', @pad_character) + @string
          ELSE @string
        END
        ))
END

যাতে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:

select dbo.f_pad_before('aaa', 10, '_')

এটি আসলে একটি ইউডিএফ ব্যবহার করা হয় যা কিছু ডেটা মেনে চলার জন্য আরও কয়েকটি কাজ করতে হয়।
ক্যাড রক্স 16

আপনি চর এবং বার্চর ধরণের সংমিশ্রণ করলে এটিও পুরোপুরি কাজ করে।
জিমি বেকার

2

আমি ভিএনআরকস সমাধানটি পছন্দ করেছি, এটি এটি একটি ইউডিএফ আকারে

create function PadLeft(
      @String varchar(8000)
     ,@NumChars int
     ,@PadChar char(1) = ' ')
returns varchar(8000)
as
begin
    return stuff(@String, 1, 0, replicate(@PadChar, @NumChars - len(@String)))
end

2

এই প্যাড বাম করার একটি সহজ উপায়:

REPLACE(STR(FACT_HEAD.FACT_NO, x, 0), ' ', y)

xপ্যাড নম্বরটি কোথায় এবং yপ্যাডের অক্ষর।

নমুনা:

REPLACE(STR(FACT_HEAD.FACT_NO, 3, 0), ' ', 0)

বাম প্যাডিং নম্বরগুলি আলাদা বিষয়ে কথা হবে বলে মনে হচ্ছে 1হয়ে 001
মার্টিন স্মিথ


1

এসকিউএল সার্ভার 2005 এবং পরে আপনি এটি করার জন্য একটি সিএলআর ফাংশন তৈরি করতে পারেন।


1

এটি সম্পর্কে:

replace((space(3 - len(MyField))

3 zerosপ্যাড করার সংখ্যা


এটি আমাকে সহায়তা করেছে: কনক্যাট (রিপ্লেস (স্পেস (@ এন - লেন্থ (@ জাস্টার)), '', '0'), @ জাস্ট্র)
ইঙ্গহাম

1

আমি আশা করি এটা কারো সাহায্যে লাগবে.

STUFF ( character_expression , start , length ,character_expression )

select stuff(@str, 1, 0, replicate('0', @n - len(@str)))

0

আমি এটি ব্যবহার করি এটি আপনাকে ফলাফলের দৈর্ঘ্য নির্ধারণ করার পাশাপাশি কোনও ডিফল্ট প্যাডিং চরিত্রের কোনও সরবরাহ না করে তা নির্ধারণ করতে দেয়। অবশ্যই আপনি যে সর্বাধিক মধ্যে যাচ্ছেন তার জন্য আপনি ইনপুট এবং আউটপুটটির দৈর্ঘ্য কাস্টমাইজ করতে পারেন।

/*===============================================================
 Author         : Joey Morgan
 Create date    : November 1, 2012
 Description    : Pads the string @MyStr with the character in 
                : @PadChar so all results have the same length
 ================================================================*/
 CREATE FUNCTION [dbo].[svfn_AMS_PAD_STRING]
        (
         @MyStr VARCHAR(25),
         @LENGTH INT,
         @PadChar CHAR(1) = NULL
        )
RETURNS VARCHAR(25)
 AS 
      BEGIN
        SET @PadChar = ISNULL(@PadChar, '0');
        DECLARE @Result VARCHAR(25);
        SELECT
            @Result = RIGHT(SUBSTRING(REPLICATE('0', @LENGTH), 1,
                                      (@LENGTH + 1) - LEN(RTRIM(@MyStr)))
                            + RTRIM(@MyStr), @LENGTH)

        RETURN @Result

      END

আপনার মাইলেজ পরিবর্তিত হতে পারে. :-)

জোয়ে মরগান
প্রোগ্রামার / বিশ্লেষক প্রিন্সিপাল আই
ওয়েলপয়েন্ট মেডিকেড বিজনেস ইউনিট


0

আমার সমাধানটি এখানে দেওয়া হয়েছে, যা কাটা স্ট্রিংগুলি এড়িয়ে চলে এবং সাধারণ ওল 'এসকিউএল' ব্যবহার করে। @ অ্যালেক্সকিউজ , @ কেভিন এবং @ স্ক্লাইভজকে ধন্যবাদ , যার সমাধানগুলি এই কোডের ভিত্তি।

 --[@charToPadStringWith] is the character you want to pad the string with.
declare @charToPadStringWith char(1) = 'X';

-- Generate a table of values to test with.
declare @stringValues table (RowId int IDENTITY(1,1) NOT NULL PRIMARY KEY, StringValue varchar(max) NULL);
insert into @stringValues (StringValue) values (null), (''), ('_'), ('A'), ('ABCDE'), ('1234567890');

-- Generate a table to store testing results in.
declare @testingResults table (RowId int IDENTITY(1,1) NOT NULL PRIMARY KEY, StringValue varchar(max) NULL, PaddedStringValue varchar(max) NULL);

-- Get the length of the longest string, then pad all strings based on that length.
declare @maxLengthOfPaddedString int = (select MAX(LEN(StringValue)) from @stringValues);
declare @longestStringValue varchar(max) = (select top(1) StringValue from @stringValues where LEN(StringValue) = @maxLengthOfPaddedString);
select [@longestStringValue]=@longestStringValue, [@maxLengthOfPaddedString]=@maxLengthOfPaddedString;

-- Loop through each of the test string values, apply padding to it, and store the results in [@testingResults].
while (1=1)
begin
    declare
        @stringValueRowId int,
        @stringValue varchar(max);

    -- Get the next row in the [@stringLengths] table.
    select top(1) @stringValueRowId = RowId, @stringValue = StringValue
    from @stringValues 
    where RowId > isnull(@stringValueRowId, 0) 
    order by RowId;

    if (@@ROWCOUNT = 0) 
        break;

    -- Here is where the padding magic happens.
    declare @paddedStringValue varchar(max) = RIGHT(REPLICATE(@charToPadStringWith, @maxLengthOfPaddedString) + @stringValue, @maxLengthOfPaddedString);

    -- Added to the list of results.
    insert into @testingResults (StringValue, PaddedStringValue) values (@stringValue, @paddedStringValue);
end

-- Get all of the testing results.
select * from @testingResults;

0

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

আপনি আমার কোডে দেখতে পারবেন যেখানে নতুন @ প্যাডিং ভেরিয়েবল (এবং বর্তমানে বিদ্যমান সীমাবদ্ধতা) ছাড়াও দুটির মধ্যে স্যুইচ রয়েছে। আমি উভয় রাজ্যে ফাংশন দিয়ে মৃত্যুর সময় একই ফলাফল নিয়ে আমার পদ্ধতি চালিয়েছি। কমপক্ষে এসকিউএল সার্ভার ২০১6-এ, আমি অন্যান্য দক্ষতার সাথে দক্ষতার কোনও পার্থক্য দেখছি না।

যাইহোক, আমি এখানে আমার ইউডিএফটি লিখেছি যা আমি কয়েক বছর আগে লিখেছিলাম এবং আজকের পরিবর্তনগুলি যা অন্যদের মতো অনেকটা তার মত একটি লেফট / রাইট পারম বিকল্প রয়েছে এবং কিছু ত্রুটি পরীক্ষা করে।

CREATE FUNCTION PadStringTrim 
(
    @inputStr varchar(500), 
    @finalLength int, 
    @padChar varchar (1),
    @padSide varchar(1)
)
RETURNS VARCHAR(500)

AS BEGIN
    -- the point of this function is to avoid using replicate which is extremely slow in SQL Server
    -- to get away from this though we now have a limitation of how much padding we can add, so I've settled on a hundred character pad 
    DECLARE @padding VARCHAR (100) = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    SET @padding = REPLACE(@padding, 'X', @padChar)


    SET @inputStr = RTRIM(LTRIM(@inputStr))

    IF LEN(@inputStr) > @finalLength 
        RETURN '!ERROR!' -- can search for ! in the returned text 

    ELSE IF(@finalLength > LEN(@inputStr))
        IF @padSide = 'L'
            SET @inputStr = RIGHT(@padding + @inputStr, @finalLength)
            --SET @inputStr = REPLICATE(@padChar, @finalLength - LEN(@inputStr)) + @inputStr
        ELSE IF @padSide = 'R'
            SET @inputStr = LEFT(@inputStr + @padding, @finalLength)
            --SET @inputStr = @inputStr + REPLICATE(@padChar, @finalLength - LEN(@inputStr)) 



    -- if LEN(@inputStr) = @finalLength we just return it 
    RETURN @inputStr;
END

-- SELECT  dbo.PadStringTrim( tblAccounts.account, 20, '~' , 'R' ) from tblAccounts
-- SELECT  dbo.PadStringTrim( tblAccounts.account, 20, '~' , 'L' ) from tblAccounts

0

আমার এক ফাংশন রয়েছে যা এক্স দশমিকের সাথে এলপ্যাড করে: ফাংশন তৈরি করুন [ডিবিও] [ ) শুরু হিসাবে এনভারচর (সর্বাধিক) ফেরত দিন - এখানে রিটার্নের ভেরিয়েবল ঘোষণা করুন @ তবে এনভারচার (সর্বোচ্চ)

IF LEN(@string)=@length
BEGIN
    IF CHARINDEX('.',@string)>0
    BEGIN
        SELECT @resp = CASE SIGN(@string)
            WHEN -1 THEN
                -- Nros negativos grandes con decimales
                concat('-',SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec)))
            ELSE
                -- Nros positivos grandes con decimales
                concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(@string,@length,@dec)))                  
            END
    END
    ELSE
    BEGIN
        SELECT @resp = CASE SIGN(@string)
            WHEN -1 THEN
                --Nros negativo grande sin decimales
                concat('-',SUBSTRING(replicate(@pad,@length),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
            ELSE
                -- Nros positivos grandes con decimales
                concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(@string,@length,@dec)))                  
            END                     
    END
END
ELSE
    IF CHARINDEX('.',@string)>0
    BEGIN
        SELECT @resp =CASE SIGN(@string)
            WHEN -1 THEN
                -- Nros negativos con decimales
                concat('-',SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec)))
            ELSE
                --Ntos positivos con decimales
                concat(SUBSTRING(replicate(@pad,@length),1,@length-len(@string)),ltrim(str(abs(@string),@length,@dec))) 
            END
    END
    ELSE
    BEGIN
        SELECT @resp = CASE SIGN(@string)
            WHEN -1 THEN
                -- Nros Negativos sin decimales
                concat('-',SUBSTRING(replicate(@pad,@length-3),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
            ELSE
                -- Nros Positivos sin decimales
                concat(SUBSTRING(replicate(@pad,@length),1,(@length-3)-len(@string)),ltrim(str(abs(@string),@length,@dec)))
            END
    END
RETURN @resp

শেষ


-1

দুটি দশমিক স্থানে গোলাকার সংখ্যাসূচক মানগুলি সরবরাহ করতে তবে প্রয়োজন হলে শূন্যের সাথে ডান-প্যাডযুক্ত:

DECLARE @value = 20.1
SET @value = ROUND(@value,2) * 100
PRINT LEFT(CAST(@value AS VARCHAR(20)), LEN(@value)-2) + '.' + RIGHT(CAST(@value AS VARCHAR(20)),2)

যদি কেউ খুব সুন্দরভাবে চিন্তা করতে পারে তবে এটি প্রশংসা করবে - উপরেরটিকে আনাড়ি বলে মনে হচ্ছে ।

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


1
জানেন না যে এসকিউএল সার্ভার আপনাকে এর ধরণ উল্লেখ না করেই ভেরিয়েবল ঘোষণা করতে দেয়। যাইহোক, আপনার পদ্ধতিটি অ-কর্মক্ষম ব্যক্তির জন্য "আনাড়ি" বলে মনে হচ্ছে। :)
অ্যান্ড্রি এম

-4

এখানে আমি সাধারণত একটি বার্চার প্যাড করব

WHILE Len(@String) < 8
BEGIN
    SELECT @String = '0' + @String
END

14
বাহ, এটি আশ্চর্যজনকভাবে খারাপ।
হোগান

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