এসকিউএলে "শূন্য দ্বারা বিভাজন" ত্রুটিটি কীভাবে এড়ানো যায়?


363

আমার এই ত্রুটি বার্তাটি রয়েছে:

এমএসজি 8134, স্তর 16, রাজ্য 1, লাইন 1 ভাগ করে শূন্য ত্রুটি হয়েছে।

এসকিউএল কোড লেখার সর্বোত্তম উপায় কী যাতে আমি এই ত্রুটি বার্তাটি আর কখনও দেখতে পাব না?

আমি নিম্নলিখিত দুটিও করতে পারি:

  • এমন একটি ধারা যুক্ত করুন যাতে আমার বিভাজকটি কখনই শূন্য না হয়

অথবা

  • আমি কেস স্টেটমেন্ট যুক্ত করতে পারতাম, যাতে শূন্যের জন্য একটি বিশেষ চিকিত্সা থাকে।

একটি NULLIFধারা ব্যবহার করার সবচেয়ে ভাল উপায় ?

এর চেয়ে ভাল উপায় কি আছে বা কীভাবে এটি প্রয়োগ করা যেতে পারে?


7
সম্ভবত কিছু ডেটা বৈধকরণ ক্রমযুক্ত।
অ্যান্টনি

উত্তর:


644

"বিভাগ দ্বারা শূন্য" ত্রুটি এড়াতে আমরা এটিকে এইভাবে প্রোগ্রাম করেছি:

Select Case when divisor=0 then null
Else dividend / divisor
End ,,,

তবে এখানে এটি করার একটি দুর্দান্ত উপায়:

Select dividend / NULLIF(divisor, 0) ...

এখন কেবল সমস্যাটি হল নুলিফ বিটটি মনে রাখা, যদি আমি "/" কী ব্যবহার করি।


13
"ডিভিডেন্ড / নুলিফ নির্বাচন করুন (বিভাজক, 0) ..." এটি করার একটি দুর্দান্ত উপায় s
অ্যান্ডারসন

8
@ অ্যান্ডারসন এটি মোটেও সত্য নয়। আপনি কি নিশ্চিত যে আপনি দুর্ঘটনাক্রমে IsNullপরিবর্তে ব্যবহার করেন নি NullIf? এটি নিজে চেষ্টা করো! SELECT Value,1/NullIf(Value,0)FROM(VALUES(0),(5.0),(NULL))x(Value);"বিরতি" না দিয়ে যদি আপনি বোঝাচ্ছেন কোনও নাল ফেরায়? আপনি যা চান তার সাথে এটি রূপান্তর করতে পারেন IsNullবা Coalesce
এরিক

1
@ এরিক, এটি সত্য ... দৌড়ানোর চেষ্টা করুন ... 1 / নুলিফ নির্বাচন করুন (নাল, 0) ... আপনি পেয়েছেন "নুল্লিফের সাথে প্রথম যুক্তির ধরণটি নুল স্থির হতে পারে না কারণ প্রথম যুক্তির ধরণ রয়েছে পরিচিত হতে হবে। " "Coalesce (FieldName, 0)" ব্যবহার করে এটি হ্যান্ডেল করুন ... উদাহরণস্বরূপ 1 / নুলিফ (coalesce (নাল, 0), 0) নির্বাচন করুন
জন জোসেফ

1
আপনি আমার সাথে একমত হচ্ছেন বা আমার সাথে তর্ক করছেন কিনা তা আমি জোজন জোসেফকে বলতে পারি না।
এরিক

1
@ জোজন জোসেফ আপনার কাছ থেকে পাওয়া ত্রুটিটি আরও কাছাকাছি দেখুন হ্যাঁ, SELECT 1 / NULLIF(NULL, 0)ব্যর্থ হয়েছে, তবে এটি NULLIF()প্রথম যুক্তির ডেটাটাইপ জানা দরকার। এই পরিবর্তিত উদাহরণ কাজ করে জরিমানা: SELECT 1 / NULLIF(CAST(NULL AS INT), 0)। বাস্তব জীবনে, আপনি NULLIF()একটি NULLধ্রুবক না হয়ে একটি টেবিল কলাম সরবরাহ করতে যাচ্ছেন । যেহেতু সারণী কলামগুলি পরিচিত datatypes আছে, এটি কাজ করে জরিমানা: SELECT 1 / NULLIF(SomeNullableColumn, 0) FROM SomeTable
মারেডচিজ

180

আপনি যদি শূন্য ফিরে আসতে চান তবে যদি শূন্য বিচ্যুতি ঘটে, আপনি ব্যবহার করতে পারেন:

SELECT COALESCE(dividend / NULLIF(divisor,0), 0) FROM sometable

প্রতিটি বিভাজকের জন্য যা শূন্য, আপনি ফলাফলের সেটে একটি শূন্য পাবেন।


9
কিছু মানদণ্ড প্রকাশ করে যে COALESCE ISNULL এর চেয়ে সামান্য ধীর। তবে, COALESCE স্ট্যান্ডার্ডগুলিতে তাই আরও বহনযোগ্য।
পল চেরনোচ

37
অন্য কেউ যদি তাত্ক্ষণিকভাবে এটি কেন কাজ করে না পান তবে নুলিফ (d, 0) নূন্যতম ফিরে আসবে যদি ডি 0 হয়, এসকিউএল-তে NULL দ্বারা বিভক্ত হয়ে NULL ফেরত দেয়। কোলেসেস ফলাফলের
NUL এর

16
@ এসকিউএল জর্জি আমি যখন আপনার যুক্তির সাথে একমত হই তবে দয়া করে মনে রাখবেন যে এমন কিছু ক্ষেত্রে রয়েছে যেগুলি গাণিতিকভাবে সঠিকের চেয়ে পরিসংখ্যানগতভাবে সঠিক যা তার বেশি যত্ন করে। কিছু ক্ষেত্রে পরিসংখ্যান ফাংশন ব্যবহার করার সময়, বিভাজক শূন্য হলে 0 বা এমনকি 1 একটি গ্রহণযোগ্য ফলাফল।
এথফাউড

10
কেউ আমাকে ব্যাখ্যা করতে পারেন কেন এটি খারাপ? আমি যদি একটি শতাংশ বের করার চেষ্টা করি এবং ভাগকারী শূন্য হয় তবে আমি অবশ্যই ফলাফলটি শূন্য শতাংশ হতে চাই।
টড শার্প

10
আমি মনে করি যে @ জর্জ এবং @ জেমস / উইলসন মূলত প্রশ্ন জিজ্ঞাসা করা ভুল বুঝবেন। অবশ্যই ব্যবসায়ের অ্যাপ্লিকেশন রয়েছে যেখানে গাণিতিক দৃষ্টিকোণ থেকে প্রযুক্তিগতভাবে সত্য না হলেও "0" ফিরিয়ে দেওয়া উপযুক্ত।
শান ব্রাঞ্চউ

66

শূন্য দ্বারা বিভাজনকে সম্বোধন করার চেষ্টা করার সময় এটি আমার পরিস্থিতির সেরা সমাধান বলে মনে হয়েছিল, যা আমার ডেটাতে ঘটে।

ধরুন আপনি বিভিন্ন স্কুল ক্লাবের জন্য পুরুষ-মহিলা অনুপাত গণনা করতে চান তবে আপনি আবিষ্কার করেছেন যে রিং ক্লাবের লর্ডের অনুপাত গণনা করার চেষ্টা করার সময় নিম্নলিখিত কোয়েরিটি ব্যর্থ হয় এবং একটি বিভাজন দ্বারা শূন্য ত্রুটি জারি করে :

SELECT club_id, males, females, males/females AS ratio
  FROM school_clubs;

NULLIFশূন্য দ্বারা বিভাগ এড়ানোর জন্য আপনি ফাংশনটি ব্যবহার করতে পারেন । NULLIFদুটি এক্সপ্রেশনকে তুলনা করে এবং যদি তারা সমান হয় বা অন্যথায় প্রথম অভিব্যক্তি নাল দেয়।

কোয়েরিটি আবার লিখুন:

SELECT club_id, males, females, males/NULLIF(females, 0) AS ratio
  FROM school_clubs;

NULLদেয় দ্বারা বিভক্ত যে কোনও সংখ্যা NULLএবং কোনও ত্রুটি উত্পন্ন হয় না।


6
হঁ্যা, যে হয় ভাল উপায় আছে যা অন্য উত্তর যার অনেক upvotes পেয়েছে হয়। আপনার সমাধানে আপনার কমপক্ষে একটি ন্যূনএলএল রয়েছে যা নির্দেশ করে যে আপনি সঠিক ফলাফল সরবরাহ করতে পারবেন না। তবে আপনি যদি ফলটি NULL থেকে জিরোতে রূপান্তর করেন তবে আপনি কেবল ভুল এবং বিভ্রান্তিকর ফলাফল পান।
এসকিউএল পুলিশ

8
যাইহোক, যদি আপনি একটি পুরুষ / মহিলা অনুপাত গণনা করতে চান, তাহলে আমি ভাল, মোট এটি তুলনা এই মত সুপারিশ: select males/(males+females), females/(males+females)। এটি আপনাকে ক্লাবের পুরুষ ও স্ত্রীদের শতকরা বন্টন দেবে, যেমন 31% পুরুষ, 69% মহিলা।
এসকিউএল পুলিশ

44

আপনি ক্যোয়ারির শুরুতে এটি করতে পারেন:

SET ARITHABORT OFF 
SET ANSI_WARNINGS OFF

সুতরাং আপনার যদি এমন কিছু থাকে তবে 100/0এটি NUL ফিরিয়ে দেবে। আমি এটি কেবল সাধারণ প্রশ্নের জন্যই করেছি, তাই এটি কীভাবে দীর্ঘ / জটিলগুলিকে প্রভাবিত করবে তা আমি জানি না।


1
আমার জন্য কাজ কর. আমার ক্ষেত্রে আমাকে যেখানে বিভাজনে অপারেশন ব্যবহার করতে হবে। আমি নিশ্চিত যে এখানে কোনও শূন্য বিভাজক নেই, কারণ আমি যখন যেখানে মন্তব্য করি তখন ফলাফলের শূন্য মান হয় না। তবে কোনওভাবে ক্যোয়ারী অপ্টিমাইজার ফিল্টার করার সময় শূন্য দ্বারা ভাগ করে। সেট অফ এরিচাবার্ট অফ সেট এবং এএনএসআই_ওয়ার্নিংস অফ অফ করুন - 2 দিনের শর্তে বিভক্ত হয়ে লড়াইয়ের পরে যেখানে যেখানে দফায় দফায় দফায় দফায় দফায় দফায় দফায় দফায় দফায় দফায় দফায় লড়াই করা হয়েছে। ধন্যবাদ!
huhu78

2
এটি "নোংরা" এতটাই নোংরা কিন্তু আমি এটি ভালবাসি! এটি একটি জিজ্ঞাসার প্রয়োজন যা সংহতকরণ করে এবং CASE বিবৃতি ব্যবহার করে কোনও বিকল্প ছিল না কারণ তখন আমাকে সেই কলামটি গ্রুপের মাধ্যমে যুক্ত করতে হয়েছিল যা ফলাফলগুলি পুরোপুরি পরিবর্তন করেছিল। প্রাথমিক ক্যোয়ারিকে সাবটুক্ট করা এবং তারপরে বাইরের ক্যোয়ারিতে গ্রুপ করাও ফলাফল পরিবর্তন করে কারণ বিভাগ জড়িত রয়েছে।
অ্যান্ড্রু স্টিৎজ

1
ঠিক আছে, সুতরাং আমি এখনও এই "সমাধান" পছন্দ করি তবে আপনারা অনেকেই যেমন অনুভব করেছেন, আমি অনুভব করেছি সেখানে "ক্লিনার" উপায় থাকতে হবে। আমি যদি সাবধানবাণীগুলি পুনরায় সক্ষম করতে ভুলে যাই? অথবা কেউ আমার কোড বন্ধ করেছেন (যা কখনও ঘটে না, তাই না?) এবং সতর্কতা সম্পর্কে ভাবেননি? যাইহোক, নুল্লিফ () সম্পর্কে অন্যান্য উত্তর দেখুন। আমি নুল্লিফ () সম্পর্কে জানতাম তবে বুঝতে পারিনি যে নুল দ্বারা ভাগ করা নুল ফেরত দেয় (আমি ভেবেছিলাম এটি একটি ত্রুটি হবে)। সুতরাং ... আমি নিম্নলিখিতগুলির সাথে গিয়েছিলাম: ইসনুল ((এসইউএম (foo) / নুলিফ (এসইউএম (বার), 0)), 0) এএসজি औसत
অ্যান্ড্রু স্টিৎজ

2
আমি এই সমাধান জানতাম না। আমি নিশ্চিত না যে এটি আমার পছন্দ হয়েছে তবে এটি কোনও দিন জেনে রাখা কার্যকর হবে। আপনাকে অনেক ধন্যবাদ.
হেনরিক স্টাউন পুলসন

1
এটি সবচেয়ে সহজ সমাধান, তবে মনে রাখবেন এটি কার্যকারিতা ক্ষতিগ্রস্থ করবে। ডকস.মাইক্রোসফট.এইন / ইউএসএসএইচএল / t-sql / statements /… থেকে : "এরিটিহবার্ট অফ-এফ সেট করা পারফরম্যান্স ইস্যুতে নেতৃত্বের সাথে ক্যোয়ারী অপ্টিমাইজেশনের উপর নেতিবাচক প্রভাব ফেলতে পারে।"
মনো ব্লেইন

36

আপনি কমপক্ষে কোনও ত্রুটি দিয়ে প্রশ্নটি ভাঙ্গতে থামিয়ে দিতে পারেন এবং NULLযদি শূন্য দ্বারা বিভাজন থাকে তবে ফিরে আসতে পারেন:

SELECT a / NULLIF(b, 0) FROM t 

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


32

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

উত্তর: আমার মনে হয় এখানে একটি অন্তর্নিহিত সমস্যা আছে, যা 0 দ্বারা বিভাজন আইনী নয়। এটি ইঙ্গিত দেয় যে কোনও কিছু আর্থিকভাবে ভুল। যদি আপনি শূন্য দ্বারা বিভাজক হন, আপনি এমন কিছু করার চেষ্টা করছেন যা গাণিতিকভাবে বোঝা যায় না, সুতরাং আপনি যে কোনও সংখ্যক উত্তর পেতে পারেন তা বৈধ হবে না। (এই ক্ষেত্রে নাল ব্যবহার করা যুক্তিসঙ্গত, কারণ এটি কোনও মান নয় যা পরবর্তী গাণিতিক গণনায় ব্যবহৃত হবে)।

সুতরাং এডওয়ার্ডো মন্তব্যগুলিতে জিজ্ঞাসা করেছেন "ব্যবহারকারী যদি 0 তে রাখেন তবে কী হবে?" এবং তিনি পরামর্শ দেন যে এর পরিবর্তে 0 পাওয়া ঠিক হবে। যদি ব্যবহারকারী শূন্যের পরিমাণ রাখে এবং আপনি এটিটি করার সময় 0 টি ফিরে আসতে চান, তবে আপনাকে সেই মানটি ধরতে এবং 0 ফেরত দেওয়ার জন্য ব্যবসায়ের বিধি স্তরে কোড দেওয়া উচিত ... যেখানে বিশেষ 0 থেকে বিভাজন নেই = 0।

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

ভাবুন আমি কিছু কোডিং করছি, এবং আমি এটি আঁকিয়েছি। আমার একটি বিকিরণ পরিমাপ স্কেলিং মান পড়তে হবে, তবে একটি অদ্ভুত প্রান্তের ক্ষেত্রে আমি প্রত্যাশা করি না, আমি 0 এ পড়েছি then আমি তারপরে আমার মানটি আপনার ফাংশনে ফেলে দিচ্ছি ... আপনি আমাকে 0 ফিরিয়ে দেন! হুররে, তেজস্ক্রিয়তা নেই! এটি সত্যই আছে এবং কেবলমাত্র আমি খারাপ মান দিয়ে যাচ্ছিলাম তা বাদে ... তবে আমার কোনও ধারণা নেই। আমি বিভাগটি ত্রুটি নিক্ষেপ করতে চাই কারণ এটি এমন পতাকা যা কিছু ভুল।


15
আমি একমত নই আপনার ব্যবসার নিয়মগুলি কখনই অবৈধ গণিত করা শেষ করা উচিত নয়। আপনি যদি এমন কিছু করতে থাকেন তবে সম্ভবত আপনার ডেটা মডেলটি ভুল। যখনই আপনি 0 দ্বারা বিভাজনের মুখোমুখি হন তখন আপনার চিন্তা করা উচিত যদি ডেটা 0 এর পরিবর্তে
NUL

32
আমি বিশ্বাস করতে পারি না যে আমি এমন কেউ জিজ্ঞাসা করেছি যে আমি কখনও "কোনও বাস্তব প্রোগ্রামিং করেছি?" কারণ আমি অলস হওয়ার চেয়ে এটি সঠিকভাবে করার জন্য বলছি। দীর্ঘশ্বাস
ফেলুন

11
আমি দুঃখিত, আমি আপনাকে আপত্তি জানাতে চাইনি। তবে প্রশ্নটি প্রচুর সাধারণ এলওবি অ্যাপ্লিকেশনগুলিতে পুরোপুরি বৈধ, এবং "0 দ্বারা বিভাজন আইনী নয়" এর সাথে উত্তর দেওয়া মান আইএমএইচও যোগ করে না।
এডুয়ার্ডো মোল্টেনি

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

4
@ জ্যাকডুগলাস হ্যাঁ, এটি একটি ভাল সংক্ষিপ্তসার, যা আমি সম্মত। মূলত এই প্রশ্নের উদ্ভব বলে মনে হয়েছিল "এই ত্রুটিটি গোপন করার জন্য আমি কী করতে পারি"। তার পর থেকে এটি বিকশিত হয়েছে। একটি নাল ফিরে, তিনি উত্তর অবশেষে আসে, মনে হয় এক যুক্তিসঙ্গত reponse। (আমি 0 বা অন্য কোনও নম্বর না ফেরার জন্য
দৃ strongly়ভাবে পরামর্শ দিচ্ছিলাম

28
SELECT Dividend / ISNULL(NULLIF(Divisor,0), 1) AS Result from table

নূলিফ () দিয়ে শূন্যকে ধরার পরে, তারপরে একটি ইসনুল () দ্বারা ফলস্বরূপ নাল আপনি শূন্য ত্রুটি দ্বারা আপনার বিভাজনকে রোধ করতে পারেন।


3
এর দৈর্ঘ্যের কারণে আপনার উত্তর মোছার জন্য সুপারিশ করা হয়েছে। মনে রাখবেন যে আপনি যা যা পরামর্শ দিচ্ছেন তার একটি ছোট ব্যাখ্যা যুক্ত করা সর্বদা ভাল - এমনকি এটি খুব সহজ মনে হলেও;)
ত্রিনিমন

10

"শূন্য দ্বারা বিভাজন" শূন্যের পরিবর্তে বিতর্কিত - তবে এটি একমাত্র বিকল্পও নয়। কিছু ক্ষেত্রে 1 এর সাথে প্রতিস্থাপন করা উপযুক্ত (যুক্তিসঙ্গত) উপযুক্ত। আমি প্রায়শই নিজেকে ব্যবহার করতে দেখি

 ISNULL(Numerator/NULLIF(Divisor,0),1)

যখন আমি স্কোর / গুনে শিফট দেখছি এবং আমার কাছে ডেটা না থাকলে 1 এ ডিফল্ট করতে চাই। উদাহরণ স্বরূপ

NewScore = OldScore *  ISNULL(NewSampleScore/NULLIF(OldSampleScore,0),1) 

প্রায়শই না, আমি এই অনুপাতটিকে অন্য কোথাও গণনা করেছি (অন্তত নয় কারণ এটি কম ডিনোমিনেটরদের জন্য কিছু খুব বড় সমন্বয় কারণকে ছুঁড়ে ফেলতে পারে this এক্ষেত্রে আমি সাধারণত ওল্ডস্যাম্পলস্কোরের জন্য নিয়ন্ত্রণ করতাম একটি প্রান্তিকের চেয়ে বেশি; যা শূন্যের অবসন্ন হয়) তবে কখনও কখনও 'হ্যাক' উপযুক্ত হয় appropriate


1
@ এন ম্যাসন; হ্যাঁ, কখনও কখনও 1 একটি বিকল্প is আপনি যখন ব্যাকস্ল্যাশ টাইপ করবেন তখন কীভাবে আপনি ISNULL অংশটি মনে করবেন?
হেনরিক স্টাউন পুলসন

1
দুঃখিত হেনরিক - আমি নিশ্চিত যে আমি প্রশ্নটি বুঝতে পেরেছি না।
এন ম্যাসন

6

আমি আমার সঞ্চিত পদ্ধতির জন্য এটি পরিচালনা করতে কিছুক্ষণ আগে একটি ফাংশন লিখেছিলাম :

print 'Creating safeDivide Stored Proc ...'
go

if exists (select * from dbo.sysobjects where  name = 'safeDivide') drop function safeDivide;
go

create function dbo.safeDivide( @Numerator decimal(38,19), @divisor decimal(39,19))
   returns decimal(38,19)
begin
 -- **************************************************************************
 --  Procedure: safeDivide()
 --     Author: Ron Savage, Central, ex: 1282
 --       Date: 06/22/2004
 --
 --  Description:
 --  This function divides the first argument by the second argument after
 --  checking for NULL or 0 divisors to avoid "divide by zero" errors.
 -- Change History:
 --
 -- Date        Init. Description
 -- 05/14/2009  RS    Updated to handle really freaking big numbers, just in
 --                   case. :-)
 -- 05/14/2009  RS    Updated to handle negative divisors.
 -- **************************************************************************
   declare @p_product    decimal(38,19);

   select @p_product = null;

   if ( @divisor is not null and @divisor <> 0 and @Numerator is not null )
      select @p_product = @Numerator / @divisor;

   return(@p_product)
end
go

2
হাই রন, নিস সলিউশন, এটির একটি সীমিত ডাটা টাইপ (4 দশমিক জায়গা) ব্যতীত এবং আমাদের @ বিভাজনগুলিও নেতিবাচক হতে পারে। এবং আপনি কীভাবে এটি ব্যবহারের প্রয়োগ করবেন? টিআইএ হেনরিক স্টাউন পুলসন
হেনরিক স্টাউন পলসন

1
আমি একটি নির্দিষ্ট সমস্যার দৃশ্যটি হ্যান্ডেল করতে খুব তাড়াতাড়ি ড্যাশ করেছি। একক বিকাশকারী অ্যাপ্লিকেশন, সুতরাং আমার স্মৃতিশক্তি ব্যতীত কার্যকরকরণ এতটা কঠিন নয়। :-)
রন সেভেজ

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

4
আমি মার্ক সোউলের এই দৃ with়তার সাথে একমত হয়েছি যে স্কেলারের কাজটি ব্যথার কারণ হবে। এটি টি-এসকিউএল-এ একটি ভয়ঙ্কর পরামর্শ, এটি করবেন না! স্কেলার ফাংশনগুলি হল পারফরম্যান্স নষ্টকারী! ইন-লাইন টেবিলের মূল্যবান ফাংশনটি এসকিউএল সার্ভারে কেবলমাত্র ভাল ব্যবহারকারীর ফাংশন (সম্ভবত সিএলআর ফাংশনগুলি বাদ দিতে পারে যা ভাল সম্পাদন করতে পারে)।
দাভোস

4
  1. শেকার Divisor-বিহীন হতে বাধ্য করে এমন একটি CHECK সীমাবদ্ধতা যুক্ত করুন
  2. এই ফর্মটিতে একটি বৈধকারক যুক্ত করুন যাতে ব্যবহারকারী এই ক্ষেত্রে শূন্য মানগুলি প্রবেশ করতে না পারে।

1
আমি আরও বেশি করে চেক সীমাবদ্ধতাগুলি পছন্দ করতে শুরু করি।
হেনরিক স্টাউন পুলসন

4

এসকিউএল আপডেট করার জন্য:

update Table1 set Col1 = Col2 / ISNULL(NULLIF(Col3,0),1)

3
হাই বিজয়, হ্যাঁ, এটি কার্যকর হবে, তবে ... আমি ইসনুল অংশটি সম্পর্কে সতর্ক থাকব, যেখানে আপনি NUL দ্বারা বিভাজন শেষ করবেন। আমি বরং ব্যবহারকারীকে সিগন্যাল করব যে ফলাফলটি অজানা কারণ বিভাজকটি শূন্য।
হেনরিক স্টাউন পুলসন

2
ধন্যবাদ আমাকে জটিল সাবকোয়্যারিতে বাঁচিয়েছে, ধন্যবাদ।
কিউমাস্টার

3

কোনও যাদু বৈশ্বিক সেটিং নেই '0 টি ব্যতিক্রম দ্বারা টার্ন বিভাগ'। অপারেশনটি নিক্ষেপ করতে হবে, যেহেতু x / 0 এর গাণিতিক অর্থ NULL অর্থের চেয়ে পৃথক, সুতরাং এটি NULL ফিরে আসতে পারে না। আমি ধরে নিলাম আপনি সুস্পষ্টের যত্ন নিচ্ছেন এবং আপনার প্রশ্নের মধ্যে এমন শর্ত রয়েছে যা 0 বিভাজকের সাথে রেকর্ডগুলি সরিয়ে ফেলতে হবে এবং বিভাগটি কখনই মূল্যায়ন করতে পারে না। স্বাভাবিক 'gotcha হয়' ছাড়া অধিকাংশ ডেভেলপার এসকিউএল পদ্ধতিগত ভাষায় মত আচরণ আশা এবং লজিক্যাল অপারেটর শর্ট সার্কিট অফার, কিন্তু এটা আছে না । আমি আপনাকে এই নিবন্ধটি পড়ার পরামর্শ দিচ্ছি: http://www.sqlmag.com/Articles/ArticleID/9148/pg/2/2.html


4
এখানে এমন একটি "ম্যাজিক গ্লোবাল সেটিং" রয়েছে; অ্যারিটাবার্ট অফ করুন।
ডেভিড ম্যানহিম

3

এখানে এমন একটি পরিস্থিতি যেখানে আপনি শূন্য দ্বারা ভাগ করতে পারেন। ব্যবসায়ের নিয়ম হ'ল জায়ের পালা গণনা করার জন্য, আপনি কোনও সময়ের জন্য বিক্রি হওয়া সামগ্রীর জন্য ব্যয় করেন, বার্ষিক করুন। আপনার বার্ষিক সংখ্যা হওয়ার পরে, আপনি পিরিয়ডের জন্য গড় তালিকা অনুসারে ভাগ করে নিন।

আমি তিন মাসের সময়কালে ঘটে যাওয়া জায়গুলির সংখ্যা গণনা করে দেখছি। আমি গণনা করেছি যে আমার কাছে কস্ট অফ গুডস বিক্রি হয়েছে তিন মাসের সময়কালে $ 1000 ডলারে। বিক্রয় বার্ষিক হার $ 4,000 ($ 1,000 / 3) * 12। প্রারম্ভিক জায়টি 0 হয়। সমাপ্তি তালিকাটি 0 হয় আমার গড় তালিকা এখন 0 হয় I আমার প্রতি বছর 000 4000 বিক্রয় আছে, এবং কোনও জায় নেই। এটি অসীম সংখ্যক টার্ন দেয়। এর অর্থ হ'ল আমার সমস্ত জায় গ্রাহকরা রূপান্তরিত এবং ক্রয় করছেন।

ইনভেন্টরি টার্নগুলি কীভাবে গণনা করা যায় এটি একটি ব্যবসায়িক নিয়ম।


3
হ্যাঁ, আপনি তারপর আছে অসীম পালাক্রমে সংখ্যা। সুতরাং এই ক্ষেত্রে যদি আপনার শূন্যের সাথে ভাগ হয়, তবে আপনার '# আইএনএফ' এর মতো কিছু প্রদর্শন করা উচিত।
এসকিউএল পুলিশ

1
"প্রারম্ভিক জায় 0। শেষ সমাপ্তি 0 হয়। আমার গড় তালিকা এখন 0." আপনার গণনা একটি অনুমান। কিছু সময় জায়টি ইতিবাচক হয় বা আপনি কোনও কিছু শিপ / বিক্রয় করতে পারবেন না। ফলস্বরূপ আপনি যদি + with থেকে অসন্তুষ্ট হন, গড় অনুসন্ধানের আরও ভাল অনুমান ব্যবহার করুন।
টম ব্লডজেট

2
CREATE FUNCTION dbo.Divide(@Numerator Real, @Denominator Real)
RETURNS Real AS
/*
Purpose:      Handle Division by Zero errors
Description:  User Defined Scalar Function
Parameter(s): @Numerator and @Denominator

Test it:

SELECT 'Numerator = 0' Division, dbo.fn_CORP_Divide(0,16) Results
UNION ALL
SELECT 'Denominator = 0', dbo.fn_CORP_Divide(16,0)
UNION ALL
SELECT 'Numerator is NULL', dbo.fn_CORP_Divide(NULL,16)
UNION ALL
SELECT 'Denominator is NULL', dbo.fn_CORP_Divide(16,NULL)
UNION ALL
SELECT 'Numerator & Denominator is NULL', dbo.fn_CORP_Divide(NULL,NULL)
UNION ALL
SELECT 'Numerator & Denominator = 0', dbo.fn_CORP_Divide(0,0)
UNION ALL
SELECT '16 / 4', dbo.fn_CORP_Divide(16,4)
UNION ALL
SELECT '16 / 3', dbo.fn_CORP_Divide(16,3)

*/
BEGIN
    RETURN
        CASE WHEN @Denominator = 0 THEN
            NULL
        ELSE
            @Numerator / @Denominator
        END
END
GO

আমি আপনার সমাধানটি পছন্দ করি না, কারণ একটি ইউডিএফ ব্যবহার করা প্রশ্নটিকে একক থ্রেড মোডে চালিত করতে বাধ্য করে। আমি আপনার পরীক্ষা সেটআপ পছন্দ। আমি আমাদের সমস্ত ইউডিএফগুলিতে এটি রাখতে চাই।
হেনরিক স্টাউন পুলসন

আমার জন্য এই সমাধানটি নিখুঁত এবং মার্জিত
পেইডিম্যান্ট

@Payedimaunt; হ্যাঁ, ইউডিএফগুলি খুব মার্জিত কোডে নেতৃত্ব দেয়। তবে এটি ভাল পারফর্ম করে না। এটি "ঘুমের বড়িগুলিতে অভিশাপ"। :-) এটি একটি সাধারণ পরিবর্তে dbo.Divide লিখতে মনে রাখা কঠিন "/"
হেনরিক Staun Poulsen

1

ক্লোজ ক্লজ ব্যবহার করে ডেটা ফিল্টার করুন যাতে আপনি 0 টি মান না পান।


1

কখনও কখনও, 0 উপযুক্ত নাও হতে পারে তবে কখনও কখনও 1 টিও উপযুক্ত হয় না। কখনও কখনও 1 বা 100-শতাংশ পরিবর্তন হিসাবে বর্ণিত 0 থেকে 100,000,000 থেকে লাফানোও বিভ্রান্তিকর হতে পারে। 100,000,000 শতাংশ সেই পরিস্থিতিতে উপযুক্ত হতে পারে। শতাংশ বা অনুপাতের ভিত্তিতে আপনি কী ধরণের সিদ্ধান্তে উঠতে চান তা নির্ভর করে।

উদাহরণস্বরূপ, খুব স্বল্প বিক্রয়কারী আইটেমটি ২-৪ টি বিক্রি হতে শুরু করে এবং একটি খুব বড় বিক্রির আইটেমটি এক হাজার থেকে ২,০০,০০০ বিক্রি করে কোনও বিশ্লেষক বা পরিচালকের কাছে ভিন্ন ভিন্ন জিনিস বোঝাতে পারে তবে এটি উভয়ই ১০০% বা ১ এর মধ্য দিয়ে আসতে পারে পরিবর্তন.

বৈধ ডেটার সাথে মিশ্রিত 0% বা 100% সারিগুলির একগুচ্ছ স্কাউয়ারের চেয়ে নূন্যমূল্যগুলি বিচ্ছিন্ন করা সহজ হতে পারে। প্রায়শই, ডিনোমিনেটরে 0 টি একটি ত্রুটি বা অনুপস্থিত মান নির্দেশ করতে পারে এবং আপনার ডেটাসেটকে আরও পরিশ্রুত দেখানোর জন্য আপনি কেবল একটি নির্বিচার মান পূরণ করতে চাইবেন না।

CASE
     WHEN [Denominator] = 0
     THEN NULL --or any value or sub case
     ELSE [Numerator]/[Denominator]
END as DivisionProblem

1
আমি দেখতে পেয়েছি যে সমস্যাটি যখনই আপনি কোনও বিভাগ করতে চান তখন কিছু করা মনে রাখবেন। আপনি যদি CASE বা NULLIF যোগ করার কথা মনে করতে ব্যর্থ হন তবে আপনি সোমবার সকালে এক্স সপ্তাহে একটি সমর্থন ক্ষেত্রে পান। আমি ওটা ঘৃণা করি.
হেনরিক স্টাউন পুলসন

1

আমি এটি ঠিক করেছি:

আইআইএফ (মান! = 0, মোট / মান, 0)

এটি একটি আপডেটে আবৃত হতে পারে:

SET Pct = IIF (মান! = 0, মোট / মান, 0)

বা একটি নির্বাচন:

IIF (মান! = 0, মোট / মান, 0) নির্বাচন করুন টেবিলের নাম থেকে Pct;

থটস?


আমি এবং অন্যরা দেখতে পাই যে "অজানা" কে শূন্যের সাথে প্রতিস্থাপন করা একটি বিপজ্জনক সমাধান is আমি অনেক বেশি পছন্দ করি তবে মুশকিল হ'ল সব বিভাগে আইএফ বা নুলিফ যুক্ত করা মনে রাখা!
হেনরিক স্টাউন পুলসন

0

কলটি প্রোগ্রামে ফিরে প্রচার করার সময় আপনি ত্রুটিটি যথাযথভাবে পরিচালনা করতে পারেন (বা এটি যা চান তা যদি তা উপেক্ষা করেন)। সি # তে এসকিউএল-তে ঘটে যাওয়া কোনও ত্রুটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে যা আমি অন্য কোডের ত্রুটির মতো আমার কোডটি ধরতে পারি এবং তারপরে হ্যান্ডেল করতে পারি।

আমি বেসকার সাথে একমত যে আপনি ত্রুটিটি আড়াল করতে চান না। আপনি পারমাণবিক চুল্লি নিয়ে কাজ করছেন না তবে সাধারণভাবে ত্রুটিগুলি আড়াল করা খারাপ প্রোগ্রামিং অনুশীলন। বেশিরভাগ আধুনিক প্রোগ্রামিং ল্যাঙ্গুয়েজ ত্রুটি / স্থিতির কোড সহ প্রকৃত রিটার্ন মানকে ডিকল করার জন্য কাঠামোগত ব্যতিক্রম হ্যান্ডলিং কার্যকর করার একটি কারণ is আপনি গণিত করার সময় এটি বিশেষভাবে সত্য। সবচেয়ে বড় সমস্যাটি হ'ল আপনি ভুল হিসাবে 0 টি ফিরে আসার সাথে সাথে 0 বা একটি 0 এর মধ্যে পার্থক্য করতে পারবেন না। পরিবর্তে যে কোনও মান ফেরত হ'ল তা গণিত মান এবং কোনও কিছু ভুল হলে একটি ব্যতিক্রম নিক্ষেপ করা হয়। আপনি কীভাবে ডেটাবেস অ্যাক্সেস করছেন এবং কোন ভাষাটি আপনি ব্যবহার করছেন তার উপর নির্ভর করে এটি অবশ্যই পৃথক হবে তবে আপনি যে ত্রুটি বার্তাটি মোকাবেলা করতে পারবেন তা সর্বদা সক্ষম হওয়া উচিত।

try
{
    Database.ComputePercentage();
}
catch (SqlException e)
{
    // now you can handle the exception or at least log that the exception was thrown if you choose not to handle it
    // Exception Details: System.Data.SqlClient.SqlException: Divide by zero error encountered.
}

1
আমি মনে করি আমরা সবাই একমত যে 0 টি দিয়ে ত্রুটিটি আড়াল করা কোনও সমাধান নয়। আমি যা প্রস্তাব করি তা হ'ল আমাদের কোডটি এমন লেখা যাতে প্রতিটি "/" একটি "নুলিফ" অনুসরণ করে। এইভাবে আমার রিপোর্ট / পারমাণবিক চুল্লিটি একা রাখা হয়নি, তবে সেই সমস্যাযুক্ত ত্রুটি Msg 8134 এর পরিবর্তে একটি "NULL" দেখানো হচ্ছে cause কারণ, বিভাজক 0 হলে আমার যদি কোনও আলাদা প্রক্রিয়া প্রয়োজন, তবে বেসকা এবং আমি সম্মত। আমাদের এটি কোড করা দরকার। প্রতিবার "/" লিখলে এটি করা কেবল কঠিন। "/ NULLIF" প্রতিবার করা অসম্ভব।
হেনরিক স্টাউন পুলসন

0

NULLIF(exp,0)এইভাবে ব্যবহার করুন -NULLIF(ISNULL(exp,0),0)

NULLIF(exp,0)বিরতি যদি এক্সপ হয় nullতবে NULLIF(ISNULL(exp,0),0)ভাঙবে না


1
আমি নুল্লিফ (এক্সপ্রেস, 0) পেতে পারি না, যদি 0 জিরো হয় তবে ও নয়। চেষ্টা করুন @I INT SELECT 1 / নুলিফ (@ আই, 0) আপনি এটি ব্রেক করতে পারেন কিনা তা দেখতে ডিক্লেয়ার করুন।
হেনরিক স্টাউন পুলসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.