الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

خطأ غريب عند تنفيذ أمر UPDATE

مغلقمُجاب
بدأه ABC123 في 7 فبراير 2013 · 7 رد · 968 مشاهدة · في قواعد بيانات Microsoft SQL Server
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السادة أعضاء المنتدى الكرام

 

السلام عليكم ورحمة الله وبركاتة

 

عندي قاعدة بيانات SQL SERVER تحتوي على عدة جداول منها الجدولين : CARDPAR  و  PRICE

 

وعند تنفيذ هذا الأمر 

UPDATE PRICE SET POSAVE = CARDPAR.POSAVE FROM CARDPAR WHERE PRICE.NO_M = CARDPAR.NO_M

 

يظهر الخطأ التالي :

 

 

Arithmetic overflow error converting numeric to data type numeric.
The statement has been terminated.
 
مع العلم إني عندم شكيت بوجود قيم خيالية في أحد الصفوف نفذت الأمر
SELECT MAX(POSAVE) AS MAX1 FROM CARDPAR

 

وكانت النتيجة : 630571.375520

 

للمعلومية الحقلين في الجدولين من النوع : 

numeric(16,4) - NULL

 

الرجاء من عندة معلومة عن سبب هذ الخطأ إفادتنا ... ولكم جزيل الشكر والأمتنان 

#2 أفضل إجابة

السلام عليكم..

  1. ممكن التأكدمن نوع البيانات بالدقة و خصوصا الـــ Precsion  لانه لا يمكن وضع القيمة 630571.375520 في حقل من نوع numeric(16,4) .. (نظريا و لم أجرب) .
  2. حاول استخدام Cast  او التقريب round 

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

#3

الأخ حـســام جزاك الله خيرا على سرعة الرد

 

بالنسبة لتخزين القيمة فلا مشكلة فيها أطلاقاً ... فقد قمت بتنفيذ الأمر

 

UPDATE PRICE SET POSAVE = 630571.375520 WHERE NO_M = '551'

 

وتم تنفيذة بدون أي مشاكل

 

بالنسبة للنصيحة الثانية فقد أستخدمت ROUND و CAST   قبل أن أكتب المشكلة في المنتدى

 

ولكن ............... بدون أي فائدة

 

لا أدري أشعر ان الأمر غريب حقاً 

 

ومرة أخرى لك جزيل الشكر على إهتمامك

#4

السلام عليكم ..

  1. عند تنفيذ الاستعلام :
    UPDATE PRICE SET POSAVE = 630571.375520 WHERE NO_M = '551'

    فأنه يتم تنفيذه بشكل صحيح و لكن لو فتحنا الجدول مرة أخرى , سنجد أنه تم تخزين القيمة 630571.3755 أي تم أخذ اربع ارقام بعد الفاصلة و إهمال الباقي ..

  2. أي أنه كما قلت :  مستحيل أن يخزن العمود من النوع numeric(16,4) القيمة 630571.375520 أي أن هناك اختلاف في أنواع البيانات .

  3. ممكن عمل  script  للجدولين و ارسالهم لنا .

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

#5

السلام وعليكم ورحمة الله وبركاتة

 

أعتذر أخي حسام على عدم الرد لأني لم أرى ردك الأخير لإنشغالي خلال الفترة السابقة

 

كما أشكرك جزيل الشكر لإهتمامك ... وأرجو من المولى عزوجل أن يجعلة في ميزان حسناتك

 

في المشاركة السابقة أخطأت في تحديد نوع البيانات للجدولين حيث أنة

الحقل POSAVE في الجدول CARDPAR نوعة NUMERIC(38,6)

الحقل POSAVE في الجدول PRICE نوعة NUMERIC(16,4)

 

 

وحتى تكون الصورة واضحة فأن الأمور التي جربتها هي 

UPDATE PRICE SET POSAVE = ROUND(CARDPAR.POSAVE * EQUAL,4) FROM CARDPAR WHERE PRICE.NO_M = CARDPAR.NO_M

UPDATE PRICE SET POSAVE = CAST(CARDPAR.POSAVE * EQUAL AS NUMERIC(16,4)) FROM CARDPAR WHERE PRICE.NO_M = CARDPAR.NO_M

UPDATE PRICE SET POSAVE = CONVERT(NUMERIC(16,4),CARDPAR.POSAVE * EQUAL) FROM CARDPAR WHERE PRICE.NO_M = CARDPAR.NO_M

 

ولكن للأسف بائت جميع المحاولات بالفشل 

قلت في نفسي لعل السبب يرجع إلى عملية الضرب في الحقل EQUAL

فنفذت جميع الأوامر السابقة بدون عملية الضرب ولكن ....... نفس النتيجة !!!!!!!!!!!!!!

 

خطرت في بالي فكرة (غير عملية) وهي أن أغير القيم الموجودة في الجدول CARDPAR

 UPDATE CARDPAR SET POSAVE = ROUND(CARDPAR.POSAVE,4) -- TO CHANGE 4 DIGIT

 

طبعا بعد تنفيذ الأمر السابق لا يزال نوع  البيانات NUMERIC(38,6) ولكن أصبح العدد العشري يحتوي على أربع ارقام والباقي أصفار

ومن المعلوم في علم الحساب أن الأصفار يسار العدد الصحيح ليس لها قيمة والأصفار يمين العدد العشري ليس لها قيمة

وللتأكد من الأمر قمت بتنفيذ الأمر

SELECT MAX(POSAVE) FROM CARDPAR ------------------->    630571.375500

 

ثم بعد ذلك نفذت الأوامر التي بالأعلى على الجدول PRICE

ولكن للأسف نفس النتيجة

 

**************************************************************

 

بالنسبة لعمل سكريبت للجدولين فلن أستطيع وذلك لأن البيانات الموجودة فيها ملك لمؤسسة

فعدم رفع البيانات يرجع لمسألة الأمانة فقط ولكن عمدت إلى حل بديل وهو 

IF EXISTS(SELECT NAME FROM SYSOBJECTS WHERE name='CARDPAR9' AND type = 'U') DROP TABLE CARDPAR9
    CREATE TABLE CARDPAR9 (NO_M NVARCHAR(30),POSAVE NUMERIC(38,6))
IF EXISTS(SELECT NAME FROM SYSOBJECTS WHERE name='PRICE9' AND type = 'U') DROP TABLE PRICE9
    CREATE TABLE PRICE9 (NO_M NVARCHAR(30),POSAVE NUMERIC(16,4),EQUAL NUMERIC(16,4))

INSERT INTO CARDPAR9(NO_M,POSAVE) VALUES ('001',123456.123456)
INSERT INTO CARDPAR9(NO_M,POSAVE) VALUES ('002',1234567.1234567)
INSERT INTO CARDPAR9(NO_M,POSAVE) VALUES ('003',12345678.12345678)

INSERT INTO PRICE9(NO_M,POSAVE,EQUAL) VALUES ('001',333333.3333,1)
INSERT INTO PRICE9(NO_M,POSAVE,EQUAL) VALUES ('002',333333.3333,2)
INSERT INTO PRICE9(NO_M,POSAVE,EQUAL) VALUES ('003',333333.3333,3)

UPDATE PRICE9 SET POSAVE = CARDPAR9.POSAVE * EQUAL FROM CARDPAR9 WHERE PRICE9.NO_M = CARDPAR9.NO_M
UPDATE PRICE9 SET POSAVE = ROUND(CARDPAR9.POSAVE * EQUAL,4) FROM CARDPAR9 WHERE PRICE9.NO_M = CARDPAR9.NO_M
UPDATE PRICE9 SET POSAVE = CAST(CARDPAR9.POSAVE * EQUAL AS NUMERIC(16,4)) FROM CARDPAR9 WHERE PRICE9.NO_M = CARDPAR9.NO_M
UPDATE PRICE9 SET POSAVE = CONVERT(NUMERIC(16,4),CARDPAR9.POSAVE * EQUAL) FROM CARDPAR9 WHERE PRICE9.NO_M = CARDPAR9.NO_M

SELECT * FROM CARDPAR9
SELECT * FROM PRICE9

GO
USE master

 

 

العجيب في الأمر أن الأوامر نفذت بدون أية أخطاء 

مع أن السطر الأول في عملية النقل 

UPDATE PRICE9 SET POSAVE = CARDPAR9.POSAVE * EQUAL FROM CARDPAR9 WHERE PRICE9.NO_M = CARDPAR9.NO_M

 

إي أني لم أستخدم أي عملية تحويل للبيانات

 

فأين الخلل ؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#6

السلام عليكم ...

بارك الله بك أخي ...

المشكلة هي على الاغلب في بيانات الجدول CARDPAR9  حيث انه ربما يحوي قيمه فيها  أكثر من 12 خانة قبل الفاصلة مثلا لو كان لدينا :

INSERT INTO CARDPAR9(NO_M,POSAVE) VALUES ('003',-1234567899999.1234)

 سينتج الخطأ المذكور ..

الــ Round  و الــ CAST و الــ Convert  لن تعمل لانه بالأساس لدينا رقم فيه خانات أكثر من الخانات المخصصة للرقم الوجهة .

الحل : إما جعلهما من نفس نوع البيانات .. أو ايجاد دالة أو عملية حسابية لتحويل الرقم .

1

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

#7

جزاك الله خير الجزاء 

فعلاً أتضح أن بعض الصفوف في الجدول تحتوي على قيم سالبة كبيرة

 

لم تخطر ببالي القيم السالبة حيث أن هذا الحقل يشير إلى متوسط التكلفة وبالطبع لا توجد تكلفة بالسالب

إحتواء الصفوف على قيم سالبة كانت نتيجة أخطاء عملية محاسبية

 

الحمدلله  ..... إذا عرف السبب بطل العجب

 

أسأل المولى عزوجل في هذ اليوم المبارك أن يبارك لك في علمك ومالك وولدك

وأن يغفر لك ولوالديك ولكل من لة حق عليك 

وأن يفغر لنا وللمسلمين جميعا

 

آمين يا رب العالمين

 

اللهم صلي وسلم وبارك على سيدنا محمد وعلى آلة وصحبة أجمعين

#8
ABC123 كتب:

أسأل المولى عزوجل في هذ اليوم المبارك أن يبارك لك في علمك ومالك وولدك

وأن يغفر لك ولوالديك ولكل من لة حق عليك 

وأن يفغر لنا وللمسلمين جميعا

 

آمين يا رب العالمين

 

اللهم صلي وسلم وبارك على سيدنا محمد وعلى آلة وصحبة أجمعين

جزاك الله خيرا ...

و لك مثل ما ذكرت و لجميع المسلمين .. آمين ... آمين

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

هذا الموضوع مغلق.

مواضيع مشابهة