IO Engineer

مهندسی صفر و یک

IO Engineer

مهندسی صفر و یک

مشخصات بلاگ
IO Engineer

001 به دنیای صفر و یک خوش آمدید 100

بایگانی
آخرین نظرات
  • ۳ ارديبهشت ۹۵، ۱۶:۲۴ - a
    sqll2008R2
نویسندگان

تبدیل عدد به معادل حروف فارسی در SQL Server

دوشنبه, ۱۵ ارديبهشت ۱۳۹۳، ۰۵:۳۸ ب.ظ

تابع تبدیل یک عدد (مثلا 123 (صد و بیست و سه)) به حروف فارسی معادل آن را به زبان TSQL در محیط SQL SERVER 2012 را (به همراه توضیح مختصر ) برای شما آماده کردم .

تابع رو میتونید در ادامه مطلب ببینید.



ادامه مطلب :


 

----------------------------------------------------------------------------

-- برای اینکه محدودیتی در تعداد ارقام صحیح و اعشاری نداشته باشیم، پارامتر ورودی را از نوع کاراکتری می گیریم

----------------------------------------------------------------------------

CREATE FUNCTION [dbo].[DigitToPersianWord](@Number AS VARCHAR(100))

RETURNS NVARCHAR(2500)

AS

BEGIN

----------------------------------------------------------------------------

-- بررسی تهی یا خالی بودن رشته

----------------------------------------------------------------------------

       IF LEN(ISNULL(@Number, '')) = 0  RETURN NULL

 

----------------------------------------------------------------------------

-- بررسی رشته ورودی برای پیدا کردن کاراکتر غیر عددی، نقطه و منفی

-- بررسی تعداد علامت منفی و نقطه که بیشتر از یک مورد نباشند

-- بررسی اینکه علامت منفی در ابتدای رشته ورودی باشد

----------------------------------------------------------------------------

 

       IF (PATINDEX('%[^0-9.-]%', @Number) > 0)

          OR (LEN(@Number) - LEN(REPLACE(@Number, '-', '')) > 1)

          OR (LEN(@Number) - LEN(REPLACE(@Number, '.', '')) > 1)

          OR (CHARINDEX('-', @Number) > 1)

              RETURN 'عدد وارد شده معتبر نمی باشد'

----------------------------------------------------------------------------

-- بررسی صفر بودن ورودی

-- بررسی منفی بودن ورودی

----------------------------------------------------------------------------

       IF PATINDEX('%[^0]%', @Number) = 0  RETURN 'صفر'

       IF (CHARINDEX('.', @Number) = 1) SET @Number = '0' + @Number

      

       DECLARE @Negative  AS VARCHAR(5) = '';

       IF LEFT(@Number, 1) = '-'

       BEGIN

           SET @Number = SUBSTRING(@Number, 2, 100)

           SET @Negative  = 'منفی '

       END

-----------------------------------------------------------------------------

-- درج نام اعداد به فارسی در جدول مربوطه

-----------------------------------------------------------------------------

 

       DECLARE @NumTitle TABLE (val  INT,Title NVARCHAR(100));      

       INSERT INTO @NumTitle (val,Title)

       VALUES(0, ''),(1, 'یک') ,(2, 'دو') ,(3, 'سه')    ,(4, 'چهار'),(5, 'پنج'),(6, 'شش'),(7, 'هفت'),(8, 'هشت')

              ,(9, 'نه'),(10, 'ده'),(11, 'یازده'),(12, 'دوازده'),(13, 'سیزده'),(14, 'چهارده')      ,(15, 'پانزده'),(16, 'شانزده')

              ,(17, 'هفده'),(18, 'هجده'),(19, 'نوزده'),(20, 'بیست'),(30, 'سی'),(40, 'چهل'),(50, 'پنجاه'),(60, 'شصت'),(70, 'هفتاد'),(80, 'هشتاد'),(90, 'نود'),(100, 'صد')

              ,(200, 'دویست'),(300, 'سیصد'),(400, 'چهارصد'),(500, 'پانصد'),(600, 'ششصد'),(700, 'هفتصد'),(800, 'هشتصد'),(900, 'نهصد')

      

       DECLARE @PositionTitle TABLE (id  INT,Title NVARCHAR(100));               

       INSERT INTO @PositionTitle (id,title)

       VALUES (1, '')       ,(2, 'هزار'),(3, 'میلیون'),(4, 'میلیارد'),(5, 'تریلیون')

              ,(6, 'کوادریلیون'),(7, 'کوینتیلیون'),(8, 'سیکستیلون'),(9, 'سپتیلیون'),(10, 'اکتیلیون'),(11, 'نونیلیون'),(12, 'دسیلیون')

              ,(13, 'آندسیلیون'),(14, 'دودسیلیون'),(15, 'تریدسیلیون'),(16, 'کواتردسیلیون'),(17, 'کویندسیلیون'),(18, 'سیکسدسیلیون'),(19, 'سپتندسیلیون'),(20, 'اکتودسیلیوم'),(21, 'نومدسیلیون')         

      

       DECLARE @DecimalTitle TABLE (id  INT,Title NVARCHAR(100));          

       INSERT INTO @DecimalTitle (id,Title)

       VALUES( 1 ,'دهم' ),(2 , 'صدم'),(3 , 'هزارم'),(4 , 'ده-هزارم'),(5 , 'صد-هزارم'),(6 , 'میلیون ام')

              ,(7 , 'ده-میلیون ام'),(8 , 'صد-میلیون ام'),(9 , 'میلیاردم'),(10 , 'ده-میلیاردم')

       ---------------------------------------------------------------------

       -- حذف صفرهای غیرضروری موجود در اعشار

       ---------------------------------------------------------------------

       DECLARE @IntegerNumber NVARCHAR(100),

                     @DecimalNumber NVARCHAR(100),

                     @PointPosition INT = CASE CHARINDEX('.', @Number) WHEN 0 THEN LEN(@Number) + 1 ELSE CHARINDEX('.', @Number) END

       SET @Number = replace(rtrim(replace(@Number,'0',' ')),' ','0');

       SET @IntegerNumber = LEFT(@Number, @PointPosition - 1)

       SET @DecimalNumber = SUBSTRING(@Number, @PointPosition + 1 , LEN(@Number))

 

 

       SET @Number= @IntegerNumber

----------------------------------------------------------------------------------

-- جداسازی رقم صحیح و اعشاری

----------------------------------------------------------------------------------

       DECLARE @Num AS INT

       DECLARE @MyNumbers TABLE (id INT IDENTITY(1, 1), Val1 INT, Val2 INT, Val3 INT)

      

       WHILE (@Number) <> '0'

       BEGIN

           SET @Num = CAST(SUBSTRING(@Number, LEN(@Number) -2, 3)AS INT)   

          

              INSERT INTO @MyNumbers

              SELECT (@Num % 1000) -(@Num % 100),

              CASE

                     WHEN @Num % 100 BETWEEN 10 AND 19 THEN @Num % 100

                     ELSE (@Num % 100) -(@Num % 10)

              END,

              CASE

                     WHEN @Num % 100 BETWEEN 10 AND 19 THEN 0

                     ELSE @Num % 10

              END

          

           IF LEN(@Number) > 2

               SET @Number = LEFT(@Number, LEN(@Number) -3)

           ELSE

               SET @Number = '0'

       END

-----------------------------------------------------------------------------------     

-- جدا کردن سه رقم سه رقم برای بدست آوردن یکان، دهگان و صدگان

-----------------------------------------------------------------------------------     

       DECLARE @PersianWord AS NVARCHAR(2000) = '';

 

       SELECT @PersianWord += REPLACE(REPLACE(LTRIM(RTRIM(nt1.Title + ' ' + nt2.Title + ' ' + nt3.title)),'  ',' '),' ', ' و ')

              + ' ' + pt.title + ' و '

       FROM   @MyNumbers  AS mn

              INNER JOIN @PositionTitle pt

                   ON  pt.id = mn.id

              INNER JOIN @NumTitle nt1

                   ON  nt1.val = mn.Val1

              INNER JOIN @NumTitle nt2

                   ON  nt2.val = mn.Val2

              INNER JOIN @NumTitle nt3

                   ON  nt3.val = mn.Val3

       WHERE  (nt1.val + nt2.val + nt3.val > 0)

       ORDER BY pt.id DESC

      

       IF @IntegerNumber ='0' 

              SET @PersianWord = CASE WHEN PATINDEX('%[^0]%', @DecimalNumber) > 0 THEN @Negative ELSE '' END + 'صفر'

       ELSE

              SET @PersianWord = @Negative  + LEFT (@PersianWord, LEN(@PersianWord) - 2)

             

    DECLARE @PTitle NVARCHAR(100) = ISNULL((SELECT Title FROM @DecimalTitle WHERE id=LEN(@DecimalNumber)),'')

       SET @PersianWord += ISNULL(' ممیز '+ [dbo].[DigitToPersianWord](@DecimalNumber) + ' ' + @PTitle,'')

       RETURN @PersianWord

END

 

 

 

 

نمونه کوئری اعمال شده :

SELECT dbo.DigitToPersianWord('321654987496.12345')

نتیجه حاصل :

سیصد و بیست و یک میلیارد و ششصد و پنجاه و چهار میلیون و نهصد و هشتاد و هفت هزار و چهارصد و نود و شش  ممیز دوازده هزار و سیصد و چهل و پنج  صد-هزارم

 

 

 

  • منتظر

نظرات  (۱۷)

میشه شمارتونو برای تماس بگید ؟ میخام در مورد پروژه باهاتون صحبت کنم خیلی عجله ایه ؟

ممنون.

پاسخ:
**********
سلام این برنامه در sql 2008 اجرا نمبشه این ارور را می دهد

Msg 195, Level 15, State 10, Procedure DigitToPersianWord, Line 121
'DigitToPersianWord' is not a recognized built-in function name.

قضیه چیه؟
پاسخ:
سلام
اسم تابع رو در ابتدا و انتهای تابع به [dbo].[DigitToPersianWord] تغییر بده مشکل حل میشه.
برنامه تصحیح و تست شد.
سلام
با عرض سلام و خسته نباشید خدمت شما دوست گرامی
ازتون بسیار بسیار سپاسگزارم
ایشالا که هرچی میخوای خدا بهت بده
پاسخ:
شما بزرگوارید
راستی یه سوال داشتم
ببخشید این برنامه با sql 2008 هم جواب میده؟
پاسخ:
بله
معذرت میخوام این eror چه معنایی داره؟
Msg 2714, Level 16, State 3, Procedure DigitToPersianWord, Line 177
There is already an object named 'DigitToPersianWord' in the database.
پاسخ:
میگه تابعی به این نام قبلا ایجاد شده و داخل دیتابیس یه تابع با این نام وجود داره .
اگه میخای تغییرش بدی فقط create رو به alter تغییر بده
سلام
تشکر از زحمتتان 
در SQL2014 فقط ؟؟؟؟؟ برمی گرداند! چطور میشه حلش کرد؟
پاسخ:
با چه زبانی به بانک وصل میشی ؟
هنگام ایجاد بانک collation بانک رو روی persian_100 بزار یا موقع درج و خوندن از N قبل اسم تیبلهات استفاده کن.
اگه موفق نشدی یا توضیح بیشتر بده یا کدت رو همراه با کوئریت ارسال کن تا بررسی بشه.
موفق باشی
معذرت از مزاحمت مجدد . collation را هم عوض کردم (با کلی دردسر) اما باز هم همان . حتی وقتی با دستور select تو خود sql بدون وصل شدن به جایی این کار می کنم هم همین است . مثل این دستور :
select dbo.DigitToPersianWord(123)
پاسخ:
سلام
اسکریپت زیر رو دانلود کن بعد روی بانکت اجرا کن
http://1o2.ir/68riu

کوئریت رو اجرا کن
با سلام و خسته نباشید خدمت شما دوست عزیز

از کدهای عالیتون خیلی خیلی ممنونم فقط ببخشید یک سئوال داشتم آیا کدها تست شده هستند و اصلا مشکلی ندارند یعنی من با خیال راحت در پروژه هام استفاده بکنم آیا کدها باگ ندارند

ممنون می شوم راهنمایی کنید

با تشکر از شما
این کد صفرهای اخر عددی که اعشار نداشته باشه را نمیشناسه
مثلا :select dbo.DigitToPersianWord('3453453400')
میشه : سی و چهار میلیون و پانصد و سی و چهار هزار و پانصد و سی و چهار
sqll2008R2
آقا یعنی واقعا کار جالبی انجام دادین. خیلی خیلی ممنون. 
عزا گرفته بودم که چیکار کنم.
www.a00b.com

سلام خیلی عالیه و خیلی هم خوب نوشته شده فقط یه ایراد داره 

select [dbo].[DigitToPersianWord]('940000')

مقدار بازگشتی غلط میده نو و چهار
البته این فقط یه مثال بود
با تشکر از شما

سلام محترم این کد که شما نوشته اید درست است اما زمانی که اعداد را وارد میکنم به این صورت (select duo.digitToPersionWord(123546 نتیجه اش میشه ؟؟؟؟؟؟؟؟؟شوالیه

 

  • مهدی رحیمی
  • سلام دوست عزیز توی Collation های غیر عربی و فارسی مشکل داره که من با اجازتون درستش رو نوشتم و میزارم اینجا

    ----------------------------------------------------------------------------

    -- برای اینکه محدودیتی در تعداد ارقام صحیح و اعشاری نداشته باشیم، پارامتر ورودی را از نوع کاراکتری می گیریم

    ----------------------------------------------------------------------------
    --SELECT [dbo].[DigitToPersianWord]('139541')
    alter FUNCTION [dbo].[DigitToPersianWord](@Number AS VARCHAR(100))

    RETURNS NVARCHAR(2500)

    AS

    BEGIN

    ----------------------------------------------------------------------------

    -- بررسی تهی یا خالی بودن رشته

    ----------------------------------------------------------------------------

           IF LEN(ISNULL(@Number, '')) = 0  RETURN NULL

     

    ----------------------------------------------------------------------------

    -- بررسی رشته ورودی برای پیدا کردن کاراکتر غیر عددی، نقطه و منفی

    -- بررسی تعداد علامت منفی و نقطه که بیشتر از یک مورد نباشند

    -- بررسی اینکه علامت منفی در ابتدای رشته ورودی باشد

    ----------------------------------------------------------------------------

     

           IF (PATINDEX('%[^0-9.-]%', @Number) > 0)

              OR (LEN(@Number) - LEN(REPLACE(@Number, '-', '')) > 1)

              OR (LEN(@Number) - LEN(REPLACE(@Number, '.', '')) > 1)

              OR (CHARINDEX('-', @Number) > 1)

                  RETURN N'عدد وارد شده معتبر نمی باشد'

    ----------------------------------------------------------------------------

    -- بررسی صفر بودن ورودی

    -- بررسی منفی بودن ورودی

    ----------------------------------------------------------------------------

           IF PATINDEX('%[^0]%', @Number) = 0  RETURN N'صفر'

           IF (CHARINDEX('.', @Number) = 1) SET @Number = N'0' + @Number

          

           DECLARE @Negative  AS VARCHAR(5) = N'';

           IF LEFT(@Number, 1) = N'-'

           BEGIN

               SET @Number = SUBSTRING(@Number, 2, 100)

               SET @Negative  = N'منفی '

           END

    -----------------------------------------------------------------------------

    -- درج نام اعداد به فارسی در جدول مربوطه

    -----------------------------------------------------------------------------

     

           DECLARE @NumTitle TABLE (val  INT,Title NVARCHAR(100));      

           INSERT INTO @NumTitle (val,Title)

           VALUES(0, N''),(1, N'یک') ,(2, N'دو') ,(3, N'سه')    ,(4, N'چهار'),(5, N'پنج'),(6, N'شش'),(7, N'هفت'),(8, N'هشت')

                  ,(9, N'نه'),(10, N'ده'),(11, N'یازده'),(12, N'دوازده'),(13, N'سیزده'),(14, N'چهارده')      ,(15, N'پانزده'),(16, N'شانزده')

                  ,(17, N'هفده'),(18, N'هجده'),(19, N'نوزده'),(20, N'بیست'),(30, N'سی'),(40, N'چهل'),(50, N'پنجاه'),(60, N'شصت'),(70, N'هفتاد'),(80, N'هشتاد'),(90, N'نود'),(100, N'صد')

                  ,(200, N'دویست'),(300, N'سیصد'),(400, N'چهارصد'),(500, N'پانصد'),(600, N'ششصد'),(700, N'هفتصد'),(800, N'هشتصد'),(900, N'نهصد')

          

           DECLARE @PositionTitle TABLE (id  INT,Title NVARCHAR(100));               

           INSERT INTO @PositionTitle (id,title)

           VALUES (1, '')       ,(2, N'هزار'),(3, N'میلیون'),(4, N'میلیارد'),(5, N'تریلیون')

                  ,(6, N'کوادریلیون'),(7, N'کوینتیلیون'),(8, N'سیکستیلون'),(9, N'سپتیلیون'),(10, N'اکتیلیون'),(11, N'نونیلیون'),(12, N'دسیلیون')

                  ,(13, N'آندسیلیون'),(14, N'دودسیلیون'),(15, N'تریدسیلیون'),(16, N'کواتردسیلیون'),(17, N'کویندسیلیون'),(18, N'سیکسدسیلیون'),(19, N'سپتندسیلیون'),(20, N'اکتودسیلیوم'),(21, N'نومدسیلیون')         

          

           DECLARE @DecimalTitle TABLE (id  INT,Title NVARCHAR(100));          

           INSERT INTO @DecimalTitle (id,Title)

           VALUES( 1 ,N'دهم' ),(2 , N'صدم'),(3 , N'هزارم'),(4 , N'ده-هزارم'),(5 , N'صد-هزارم'),(6 , N'میلیون ام')

                  ,(7 , N'ده-میلیون ام'),(8 , N'صد-میلیون ام'),(9 , N'میلیاردم'),(10 , N'ده-میلیاردم')

           ---------------------------------------------------------------------

           -- حذف صفرهای غیرضروری موجود در اعشار

           ---------------------------------------------------------------------

           DECLARE @IntegerNumber NVARCHAR(100),

                         @DecimalNumber NVARCHAR(100),

                         @PointPosition INT = CASE CHARINDEX('.', @Number) WHEN 0 THEN LEN(@Number) + 1 ELSE CHARINDEX('.', @Number) END

           SET @Number = replace(rtrim(replace(@Number,N'0',N' ')),N' ',N'0');

           SET @IntegerNumber = LEFT(@Number, @PointPosition - 1)

           SET @DecimalNumber = SUBSTRING(@Number, @PointPosition + 1 , LEN(@Number))

     

     

           SET @Number= @IntegerNumber

    ----------------------------------------------------------------------------------

    -- جداسازی رقم صحیح و اعشاری

    ----------------------------------------------------------------------------------

           DECLARE @Num AS INT

           DECLARE @MyNumbers TABLE (id INT IDENTITY(1, 1), Val1 INT, Val2 INT, Val3 INT)

          

           WHILE (@Number) <> N'0'

           BEGIN

               SET @Num = CAST(SUBSTRING(@Number, LEN(@Number) -2, 3)AS INT)   

              

                  INSERT INTO @MyNumbers

                  SELECT (@Num % 1000) -(@Num % 100),

                  CASE

                         WHEN @Num % 100 BETWEEN 10 AND 19 THEN @Num % 100

                         ELSE (@Num % 100) -(@Num % 10)

                  END,

                  CASE

                         WHEN @Num % 100 BETWEEN 10 AND 19 THEN 0

                         ELSE @Num % 10

                  END

              

               IF LEN(@Number) > 2

                   SET @Number = LEFT(@Number, LEN(@Number) -3)

               ELSE

                   SET @Number = '0'

           END

    -----------------------------------------------------------------------------------     

    -- جدا کردن سه رقم سه رقم برای بدست آوردن یکان، دهگان و صدگان

    -----------------------------------------------------------------------------------     

           DECLARE @PersianWord AS NVARCHAR(2000) = '';

     

           SELECT @PersianWord += REPLACE(REPLACE(LTRIM(RTRIM(nt1.Title + ' ' + nt2.Title + ' ' + nt3.title)),'  ',' '),' ', N' و ')

                  + ' ' + pt.title + N' و '

           FROM   @MyNumbers  AS mn

                  INNER JOIN @PositionTitle pt

                       ON  pt.id = mn.id

                  INNER JOIN @NumTitle nt1

                       ON  nt1.val = mn.Val1

                  INNER JOIN @NumTitle nt2

                       ON  nt2.val = mn.Val2

                  INNER JOIN @NumTitle nt3

                       ON  nt3.val = mn.Val3

           WHERE  (nt1.val + nt2.val + nt3.val > 0)

           ORDER BY pt.id DESC

          

           IF @IntegerNumber ='0'

                  SET @PersianWord = CASE WHEN PATINDEX('%[^0]%', @DecimalNumber) > 0 THEN @Negative ELSE '' END + 'صفر'

           ELSE

                  SET @PersianWord = @Negative  + LEFT (@PersianWord, LEN(@PersianWord) - 2)

                 

        DECLARE @PTitle NVARCHAR(100) = ISNULL((SELECT Title FROM @DecimalTitle WHERE id=LEN(@DecimalNumber)),'')

           SET @PersianWord += ISNULL(N' ممیز '+ [dbo].[DigitToPersianWord](@DecimalNumber) + ' ' + @PTitle,'')

           RETURN @PersianWord

    END

    سلام و درود

    بسیار عالی بود

    ممنون

  • افشین وزیری
  • سلام

    خیلی ممنون از راهنمایی شما کار من را واقعا راه انداخت

  • افشین وزیری
  • ببخشید اگر بخواهم فقط با دورقم اعشار نمایش بده چکار کنم

    ارسال نظر

    ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
    شما میتوانید از این تگهای html استفاده کنید:
    <b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
    تجدید کد امنیتی