مشكلة تشغيل غريبة في SQL Server 100-100/-100*10=0)




sql-server tsql (2)

بول هو الصحيح. - له أسبقية أقل من * ، لذلك

-A * B

يتم تحليل كـ

-(A * B)

بما أن الضرب هو ما هو عليه ، لا تلاحظ هذا عادة ، إلا عند الاختلاط في المشغلين الثنائيين الآخرين بأسبقية متساوية: / و % (ونادراً ما يتم استخدام % في تعبيرات مركبة مثل هذا). وبالتالي

C / -A * B

يتم تحليل كـ

C / -(A * B)

شرح النتائج. هذا أمر غير بديهي لأنه في معظم اللغات الأخرى ، يكون unary ناقص الأسبقية أعلى من * و / ، ولكن ليس في T-SQL ، وهذا موثق بشكل صحيح.

طريقة لطيفة (؟) لتوضيح ذلك:

SELECT -1073741824 * 2

ينتج -(1073741824 * 2) حسابيًا ، لأن -(1073741824 * 2) ينتج 2147483648 كوسيط ، والذي لا يلائم INT ، ولكن

SELECT (-1073741824) * 2

ينتج النتيجة المتوقعة -2147483648 ، وهو ما يفعل.

  • إذا قمت بتنفيذ SELECT -100/-100*10 النتيجة 0 .
  • إذا قمت بتنفيذ SELECT (-100/-100)*10 النتيجة 10 .
  • إذا قمت بتنفيذ SELECT -100/(-100*10) تكون النتيجة 0 .
  • إذا قمت بتنفيذ SELECT 100/100*10 ، فستكون النتيجة 10 .

ينص BOL :

عندما يكون لدى عاملين في تعبير نفس مستوى أسبقية المشغل ، يتم تقييمهما من اليسار إلى اليمين استنادًا إلى موضعهما في التعبير.

و

Level   Operators
  1     ~ (Bitwise NOT)
  2     * (Multiplication), / (Division), % (Modulus)
  3     + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)

هل BOL مخطئ ، أو هل أفتقد شيئًا؟ يبدو أن - يتم التخلص من الأسبقية (المتوقعة).


لاحظ في الوثائق أن ترتيب الأسبقية لـ - (Negative) هو (ربما عكسيا).

حتى تحصل بفعالية على:

-(100/-(100*10)) = 0

إذا قمت بوضعها في متغيرات ، فلن ترى هذا يحدث ، حيث لا توجد عملية أحادية تحدث بعد الضرب.

إذن ، هنا A و B متشابهان ، في حين أن C و D و E تُظهر النتيجة التي تراها (مع وجود E بين قوسين كاملين)

DECLARE @i1 int, @i2 int, @i3 int;

SELECT @i1 = -100,
       @i2 = -100,
       @i3 = 10;

SELECT @i1/@i2*@i3      [A],
       -100/(-100)*10   [B],
       -100/-100*10     [C],
       -100/-(100*10)   [D],
       -(100/-(100*10)) [E];

A - 10
B - 10
C - 0
D - 0
E - 0






operator-precedence