سؤال

ما هو ترتيب التقييم في الاستعلام التالي:

UPDATE tbl SET q = q + 1, p = q;

هذا هو، سوف "tbl"."p" يتم تعيين q أو q + 1ب هو ترتيب التقييم هنا يحكمه SQL Standard؟

شكرا.

تحديث

بعد النظر إجابة Migs, ركضت بعض الاختبارات على جميع DBS يمكنني أن أجدها. بينما لا أعرف ما يقوله المعيار، تختلف التطبيقات.

منح

CREATE TABLE tbl (p INT NOT NULL, q INT NOT NULL);
INSERT INTO tbl VALUES (1, 5);   -- p := 1, q := 5
UPDATE tbl SET q = q + 1, p = q;

لقد وجدت قيم "p" و "q" كانت:

database           p   q
-----------------+---+---
Firebird 2.1.3   | 6 | 6  -- But see "Update 2" below
InterBase 2009   | 5 | 6
MySQL 5.0.77     | 6 | 6  -- See "Update 3" below
Oracle XE (10g)  | 5 | 6
PostgreSQL 8.4.2 | 5 | 6
SQLite 3.3.6     | 5 | 6
SQL Server 2016  | 5 | 6

تحديث 2.

Firebird 2.5 يغير سلوكه لتتناسب مع غالبية محركات SQL الأخرى التي اختبرتها، وترك MySQL وحدها. دخول ملاحظات الإصدار ذات الصلة، "تغيير المنطق في جملة تعيين", ، يقترح بشدة ذلك سلوك الأغلبية هو الصحيح لكل مواصفات SQL.

لقد قمت بتشكيل MySQL للتعليق على هذا السلوك (علة لا. 52861)، كما يبدو أنهم يتوقف.

تحديث 3.

الأخطاء المذكورة أعلاه هو اليوم (2010-05-19) مغلقا، ومن المقرر تحديث الوثائق لجعل هذا السلوك صريح في كل من تحديث وصف وفي الاختلافات من SQL القياسية الجزء.

برافو، Mysql.

هل كانت مفيدة؟

المحلول

MySQL لا "اليسار إلى اليمين" التقييم و "انظر" القيم الجديدة. (تم اختباره على 5.0.45-Community-NT-Log MySQL Community Edition)

علاوة على ذلك، من دليل MySQL: "يتم تقييم مهام تحديث الجدول أحادي الجدول عموما من اليسار إلى اليمين. للحصول على تحديثات متعددة الجدول، لا يوجد أي ضمان يتم إجراء المهام بأي أمر معين."

الآن، "عموما" غامضة للغاية و "لا ضمان" سيء للغاية بالنظر إلى أن ترتيب التقييم مهم.

لذلك، من أجل الإجابة على السؤال: هل السلوك المحدد بواسطة "قياسي SQL" أم أنها مجرد اتفاقية؟


التحديث: حصلت على مواصفات SQL92 التي تحتاج إلى "بيان التحديث 13.10: تم البحث عن" عنصر "6) يتم تقييمه بشكل فعال لكل صف من T قبل تحديث أي صف من T."

IMHO لا لا لبس فيه تماما، ولكن بما يكفي للنظر في أن المعيار ليس "رؤية" نتائج التحديث الخاص بك. النظر في مثالك، والطريقة الطريقة أوراكل، postgresql و interbase تفعل ذلك.

نصائح أخرى

ال UPDATE لا يرى نتائج عملها.

p سيتم تعيين ل q اعتبارا من قبل التحديث.

سيتم تقييد التعليمات البرمجية التالية فقط الأعمدة:

DECLARE @test TABLE (p INT, q INT)

INSERT
INTO    @test
VALUES  (2, 3)

SELECT  *
FROM    @test

p    q
---  ---
  2    3

UPDATE  @test
SET     p = q,
        q = p

SELECT  *
FROM    @test

p    q
---  ---
  3    2

يجب أن يحدث الكتابة إلى الجدول بعد المعاملة التي كانت جارية جيدا عند اكتمال القراءة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top