Oracle Insert عبر التحديد من جداول متعددة حيث قد لا يحتوي جدول واحد على صف

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

  •  02-07-2019
  •  | 
  •  

سؤال

لدي عدد من جداول قيمة التعليمات البرمجية التي تحتوي على رمز ووصف بمعرف طويل.

أريد الآن إنشاء إدخال لنوع الحساب الذي يشير إلى عدد من الرموز، لذلك لدي شيء مثل هذا:

insert into account_type_standard (account_type_Standard_id,
tax_status_id, recipient_id)
( select account_type_standard_seq.nextval,
ts.tax_status_id, r.recipient_id
from tax_status ts, recipient r
where ts.tax_status_code = ?
and r.recipient_code = ?)

يؤدي ذلك إلى استرداد القيم المناسبة من جدول Tax_status وجداول المستلمين إذا تم العثور على تطابق للرموز الخاصة بكل منهما.لسوء الحظ، كود_المتلقي هو قيمة فارغة، وبالتالي فإن ؟يمكن أن تكون قيمة الاستبدال فارغة.بالطبع، لا يُرجع الارتباط الضمني صفًا، لذلك لا يتم إدراج صف في الجدول الخاص بي.

لقد حاولت استخدام NVL على؟وعلى r.recipient_id.

لقد حاولت فرض صلة خارجية على r.recipient_code = ؟عن طريق إضافة (+)، ولكنها ليست صلة صريحة، لذلك لم تقم Oracle بإضافة صف آخر.

هل يعرف أحد طريقة للقيام بذلك؟

من الواضح أنه يمكنني تعديل العبارة حتى أقوم بالبحث عن معرف المتلقي خارجيًا، وأحصل على ؟بدلاً من r.recipient_id، ولا تحدد من جدول المستلمين على الإطلاق، لكنني أفضل القيام بكل هذا في عبارة SQL واحدة.

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

المحلول

لا تعمل الصلات الخارجية "كما هو متوقع" في هذه الحالة لأنك أخبرت Oracle صراحةً أنك تريد البيانات فقط إذا كانت تلك المعايير الموجودة في هذا الجدول متطابقة.في هذا السيناريو، تصبح الصلة الخارجية عديمة الفائدة.

حل بديل

INSERT INTO account_type_standard 
  (account_type_Standard_id, tax_status_id, recipient_id) 
VALUES( 
  (SELECT account_type_standard_seq.nextval FROM DUAL),
  (SELECT tax_status_id FROM tax_status WHERE tax_status_code = ?), 
  (SELECT recipient_id FROM recipient WHERE recipient_code = ?)
)

تحرير] إذا كنت تتوقع صفوفًا متعددة من مجموعة فرعية ، فيمكنك إضافة Rownum = 1 إلى كل جملة أو استخدام مجموعة مثل Max أو Min.وهذا بالطبع قد لا يكون الحل الأفضل لجميع الحالات.

[عدل] لكل تعليق،

  (SELECT account_type_standard_seq.nextval FROM DUAL),

يمكن أن يكون عادلا

  account_type_standard_seq.nextval,

نصائح أخرى

نسخة مبسطة قليلاً من حل Oglester (لا يتطلب التسلسل تحديدًا من DUAL:

INSERT INTO account_type_standard   
  (account_type_Standard_id, tax_status_id, recipient_id) 
VALUES(   
  account_type_standard_seq.nextval,
  (SELECT tax_status_id FROM tax_status WHERE tax_status_code = ?),
  (SELECT recipient_id FROM recipient WHERE recipient_code = ?)
)

لم يكن من الواضح بالنسبة لي في السؤال ما إذا كان ts.tax_status_code هو مفتاح أساسي أو بديل أم لا.نفس الشيء مع كود_المستلم.سيكون من المفيد معرفة ذلك.

يمكنك التعامل مع احتمال أن يكون متغير الربط الخاص بك فارغًا باستخدام OR كما يلي.يمكنك ربط نفس الشيء بمتغيري الربط الأولين.

إذا كنت قلقًا بشأن الأداء، فمن الأفضل التحقق مما إذا كانت القيم التي تنوي ربطها فارغة أم لا ثم إصدار عبارة SQL مختلفة لتجنب OR.

insert into account_type_standard 
(account_type_Standard_id, tax_status_id, recipient_id)
(
select 
   account_type_standard_seq.nextval,
   ts.tax_status_id, 
   r.recipient_id
from tax_status ts, recipient r
where (ts.tax_status_code = ? OR (ts.tax_status_code IS NULL and ? IS NULL))
and (r.recipient_code = ? OR (r.recipient_code IS NULL and ? IS NULL))

يحاول:

insert into account_type_standard (account_type_Standard_id, tax_status_id, recipient_id)
select account_type_standard_seq.nextval,
       ts.tax_status_id, 
       ( select r.recipient_id
         from recipient r
         where r.recipient_code = ?
       )
from tax_status ts
where ts.tax_status_code = ?
insert into account_type_standard (account_type_Standard_id, tax_status_id, recipient_id)
select account_type_standard_seq.nextval,
   ts.tax_status_id, 
   ( select r.recipient_id
     from recipient r
     where r.recipient_code = ?
   )
from tax_status ts
where ts.tax_status_code = ?
insert into received_messages(id, content, status)
    values (RECEIVED_MESSAGES_SEQ.NEXT_VAL, empty_blob(), '');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top