PDA

View Full Version : خطا در Cast کردن مقادیر عددی



tst835
دوشنبه 11 خرداد 1394, 19:46 عصر
سلام.
من تاپیک های زیادی رو سرچ زدم ولی نتونستم مشکلم رو حل کنم به همین خاطر گفتم اینجا پست بذارم که دوستان راهنمایی کنن.
در کوئری زیر تا زمانیکه جمع مقادیر تابع sum کمتر از 2147483647 (حداکثر مقدار INT) باشه کوئری خطایی رو برنمی گردونه ولی اگر بیشتر از این مقدار باشه خطای :
Arithmetic overflow error converting expression to data type int.
رخ میده. من هر مدلی که تونستم از cast استفاده کردم ولی به جواب نرسیدم. دوستان لطف کنن بگن مشکل کوئری چیه و چرا با وجود cast کردن OverFlow رخ میده.
کوئری :


declare @pricewithpercent decimal(28,2) = 0
select @pricewithpercent = ISNULL(SUM((CAST(SaleCount as decimal(9,2)) * CAST(SubFactors.UnitPrice as decimal(12,2))) -
((CAST(SaleCount as decimal(9,2)) * CAST(SubFactors.UnitPrice as decimal(12,2))) *
(CAST(DiscountValue as decimal(8,2)) / CAST(100 as decimal(6,2)) )) ), CAST(0 as decimal)) from SubFactors

عکسی از داده های جدول (فیلد SaleCount از نوع Decimal(10,2) ، فیلد UnitPrice هم از نوع Int و DiscountValue هم از نوع Int درون جدول تعریف شدن).
131863

ASKaffash
سه شنبه 12 خرداد 1394, 07:08 صبح
سلام
همه decimal ها را به decimal(40,2) تبدیل کنید

tst835
سه شنبه 12 خرداد 1394, 08:59 صبح
سلام
همه decimal ها را به decimal(40,2) تبدیل کنید
تشکر بابت راهنمایی ولی مشکل همچنان پابرجاست.
البته sql حداکثر مقدار مجاز برای decimal رو 38 قبول کرد ولی با وجود اینکه همه مقادیر رو (38,2)decimal تعریف کردم باز هم وقتی خروجی sum بیشتر از 2147483647 میشه خطای سرریزی رخ میده :
131884

کوئری جدید :

select @pricewithpercent = ISNULL(SUM((CAST(SaleCount as decimal(38,2)) * CAST(SubFactors.UnitPrice as decimal(38,2))) -
((CAST(SaleCount as decimal(38,2)) * CAST(SubFactors.UnitPrice as decimal(38,2))) *
(CAST(DiscountValue as decimal(38,2)) / CAST(100 as decimal(38,2)) )) ), CAST(0 as decimal(38,2))) from SubFactors
نکته ای که وجود داره اینه که کوئری زیر با وجود اینکه نتیجه بالای 10 میلیارد رو برمیگیردونه با چنین خطایی روبرو نمیشه :


declare @result decimal(28,2) = 0
select @result = SUM(CAST(SaleCount as decimal(7,2)) * CAST(SubFactors.UnitPrice as decimal(11,2))) from SubFactors

خواهشی که از دوستان دارم اینه که راه حل هایی رو که پیشنهاد می دید دلیلش رو هم توضیح بدید که ضمن اینکه مشکلم حل میشه دلیل اشتباهم رو متوجه بشم که در آینده اشتباهم رو تکرار نکنم.
تشکر.

tst835
سه شنبه 12 خرداد 1394, 10:40 صبح
در حین تلاش برای رفع مشکل به یک نکته پی بردم که واسم جالبه. من خروجی تابع sum رو که سرریز میکنه با یک ReturnValue از Stored Procedure برگشت میدم. ولی همین کوئری رو که سرریز میکنه اگه مقدارش رو با پارامتر خروجی (Output) برگشت بدم هیچ خطایی رخ نمیده.
آیا ReturnValue محدودیت برگشت مقدار داره؟!!! یا اینکه نکته خاصی داره که باید رعایت بشه؟
من در نهایت خروجی که با ReturnValue برگشت میدم به اینصورته :

return @pricewithpercent
نکته : از Output نمی تونم در این مورد استفاده کنم چون درون SP یه دونه Output دارم و حتما برای این کار باید از ReturnValue استفاده کنم.

SabaSabouhi
سه شنبه 12 خرداد 1394, 12:26 عصر
در حین تلاش برای رفع مشکل به یک نکته پی بردم که واسم جالبه. من خروجی تابع sum رو که سرریز میکنه با یک ReturnValue از Stored Procedure برگشت میدم. ولی همین کوئری رو که سرریز میکنه اگه مقدارش رو با پارامتر خروجی (Output) برگشت بدم هیچ خطایی رخ نمیده.
آیا ReturnValue محدودیت برگشت مقدار داره؟!!! یا اینکه نکته خاصی داره که باید رعایت بشه؟
من در نهایت خروجی که با ReturnValue برگشت میدم به اینصورته :

return @pricewithpercent
نکته : از Output نمی تونم در این مورد استفاده کنم چون درون SP یه دونه Output دارم و حتما برای این کار باید از ReturnValue استفاده کنم.

سلام
تا جایی که من می‌دونم محدودیتی تو تعداد پارامترهای خروجی ( output ) وجود نداره.

صبا صبوحی

tst835
سه شنبه 12 خرداد 1394, 16:42 عصر
با تشکر از همه دوستان.
با اضافه کردن یک Output دیگه مشکل حل شد.
نتیجه برای دوستانی که بعدا شاید به این مشکل بر بخورن و این تاپیک رو مشاهده کنن اینکه :
1. با استفاده از Return Value فقط یک مقدار و اون هم از نوع Int (یعنی نهایتا مقدار 2147483647 رو میشه برگشت داد) پس دلیل خطای سرریزی من هم همین نکته بوده ضمن اینکه برای خروجی مد نظر من که ممکنه یک عدد اعشاری باشه به هیچ عنوان استفاده از Return Value مناسب نیست (چون یک عدد صحیح برمیگردونه).
2. توی یک SP می تونیم چندین Output داشته باشیم و مقدار برگشتی از لحاظ Data Type هم محدودیتی نداره.
منابع مفید :
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/97f2f767-453e-477b-8082-2c290fb43499/diff-bw-output-parameter-and-return-in-stored-procedure?forum=transactsql

https://msdn.microsoft.com/en-US/library/ms188655.aspx