لماذا اختيار الأعمدة المحددة ، وكل شيء ، خطأ في Oracle SQL؟

StackOverflow https://stackoverflow.com/questions/2315295

سؤال

قل لدي بيان محدد يذهب ..

select * from animals

وهذا يعطي نتيجة استعلام AA لجميع الأعمدة في الجدول.

الآن ، إذا كان العمود 42 من الجدول animals هو is_parent, ، وأريد أن أعيد ذلك في نتائجي ، بعد ذلك مباشرة gender, ، حتى أتمكن من رؤيته بسهولة أكبر. لكني أريد أيضًا جميع الأعمدة الأخرى.

select is_parent, * from animals

هذا يعود ORA-00936: missing expression.

سيعمل نفس البيان بشكل جيد في Sybase ، وأنا أعلم أنك بحاجة إلى إضافة اسم مستعار جدول إلى animals الجدول لجعله يعمل ( select is_parent, a.* from animals ani)، لكن لماذا هل يجب أن تحتاج Oracle إلى الاسم المستعار لتكون قادرة على حل الاختيار؟

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

المحلول

في الواقع ، من السهل حل المشكلة الأصلية. عليك فقط تأهيل *.

select is_parent, animals.* from animals;

يجب أن تعمل بشكل جيد. الأسماء المستعارة لأسماء الجدول تعمل أيضا.

نصائح أخرى

لا توجد ميزة في القيام بذلك في رمز الإنتاج. يجب أن نسمي بشكل صريح الأعمدة التي نريدها بدلاً من استخدام Construct * Select *.

أما بالنسبة للاستعلام المخصص ، احصل على مطور IDE - SQL ، TOAD ، PL/SQL Developer ، إلخ - والذي يتيح لنا معالجة الاستعلامات ومجموعات النتائج دون الحاجة إلى امتدادات إلى SQL.

سؤال جيد ، لقد تساءلت في كثير من الأحيان هذا بنفسي ، لكنني قبلته كأحد هذه الأشياء ...

مشكلة مماثلة هي:

sql>select geometrie.SDO_GTYPE from ngg_basiscomponent

ORA-00904: "GEOMETRIE"."SDO_GTYPE": invalid identifier

حيث Geometrie هو عمود من النوع mdsys.sdo_geometry.

أضف الاسم المستعار ويعمل الشيء.

sql>select a.geometrie.SDO_GTYPE from ngg_basiscomponent a;

الكثير من الإجابات الجيدة حتى الآن على سبب select * لا ينبغي استخدامها وأنها صحيحة تمامًا. ومع ذلك ، لا تعتقد أن أيًا منهم يجيب على السؤال الأصلي حول سبب فشل بناء الجملة المعين.

للأسف ، أعتقد أن السبب هو ... "لأنه لا".

لا أعتقد أن أي شيء يتعلق بالاستفسارات المفردة مقابل الطاولة المتعددة:

هذا يعمل بشكل جيد:

select *
from
    person p inner join user u on u.person_id = p.person_id

لكن هذا فشل:

select p.person_id, *
from
    person p inner join user u on u.person_id = p.person_id

بينما يعمل هذا:

select p.person_id, p.*, u.*
from
    person p inner join user u on u.person_id = p.person_id

قد يكون الأمر بعض الشيء التوافق التاريخي مع رمز إرث يبلغ من العمر 20 عامًا.

آخر لـ "شراء لماذا !!!" دلو ، جنبا إلى جنب مع لماذا لا يمكنك تجميعها من قبل الاسم المستعار?

حالة استخدام الاسم المستعار.* تنسيق على النحو التالي

select parent.*, child.col
from parent join child on parent.parent_id = child.parent_id

أي تحديد جميع الأعمدة من جدول واحد في صلة ، بالإضافة إلى (اختياريا) عمود واحد أو أكثر من جداول أخرى.

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

Select * في العالم الحقيقي أمر خطير فقط عند الإشارة إلى الأعمدة حسب رقم الفهرس بعد الاسترجاع بدلاً من الاسم ، فإن المشكلة الأكبر هي عدم الكفاءة عندما لا تكون جميع الأعمدة مطلوبة في مجموعة النتيجة (حركة مرور الشبكة ، وحمل وحدة المعالجة المركزية وتحميل الذاكرة). بالطبع إذا كنت تضيف أعمدة من الجداول الأخرى (كما هو الحال في هذا المثال ، فقد يكون الأمر خطيرًا لأن هذه الجداول قد تحتوي على أعمدة مع أسماء مطابقة ، select *, x في هذه الحالة ، ستفشل إذا تمت إضافة عمود X إلى الجدول الذي لم يكن لديه من قبل.

لماذا يجب أن تحتاج Oracle إلى الاسم المستعار في الجدول ليتمكن من حل الاختيار

تيراتا يتطلب الأمر نفسه. كما كلاهما قديم جدًا (ربما يسميه أفضل ناضجة :-) dbmses قد يكون هذا أسباب تاريخية.

توضيحي المعتاد هو: غير مؤهل * يعني كل شيء/جميع الأعمدة والمحلل/المحسن مرتبط ببساطة لأنك تطلب أكثر من كل شيء.

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