قواعد postgresql وقويلة الخلف () / مشكلة تسلسلي (PLAXTGRESQL خاص)

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

  •  19-09-2019
  •  | 
  •  

سؤال

عندما أستخدم قاعدة إعادة الكتابة التي تنقسم إدراج في جدول واحد إلى إدراجات إلى جداولين آخرين حيث يتمتع أحد القيم الموجودة بأحد القيم الافتراضية ("Snotherfulce") بنفس التسلسل لكلا الجداول، فإن القيم الافتراضية المدرجة مختلفة في الجداولان. ربما يكون هذا بسبب استبدال النص البسيط من قبل قاعدة إعادة الكتابة. كنت أتمنى بدلا من ذلك، سيتم حل القيمة الافتراضية أولا ثم تكتب نفس القيمة إلى كل من الجداول.

هنا مثال (كما تخمين، أحاول تنفيذ التخصص / التعميم باستخدام القواعد):

-- first and third commands can be skipped if id is defined as serial
create sequence parents_id_seq;
create table Parents(
  id integer default(nextval('parents_id_seq')) primary key,
  type varchar(50) not null check(type in ('Child1', 'Child2')),
  unique (id, type),
  attribute1 varchar(50) not null unique check(length(attribute1) > 0)
);
alter sequence parents_id_seq owned by parents.id;

يتم الاحتفاظ بالبيانات الخاصة للأطفال من النوع الأول

create table Partial_Children1(
  id integer default(nextval('parents_id_seq')) primary key,
  type varchar(50) not null check(type = 'Child1'),
  foreign key (id, type) references Parents(id, type),
  attribute2 varchar(50) not null check(length(attribute2) > 0)
);

بعد ذلك، حددت أطفالي رؤية 1 ينضم إلى كل من الجداول أعلاه (أعد كتابة طريقة العرض عن طريق إرسالها صراحة إلى ما يفعله postgresql بتحديد المشاهدات وفقا للوثائق)

create table Children1(
  id int default(nextval('parents_id_seq')),
  type varchar(50) not null check(type in ('Child1')),
  attribute1 varchar(50) not null check(length(attribute1) > 0),
  attribute2 varchar(50) not null check(length(attribute2) > 0)
);
create rule "_RETURN" as on select to Children1 do instead
  select p.*, c.attribute2
  from Parents p
    join Partial_Children1 c
      on p.id = c.id;

أخيرا، حكم إعادة كتابة أواجه مشاكل مع:

create rule ct_i_children1 as
  on insert to Children1
  do instead (
    insert into Parents(attribute1, type)
      values(new.attribute1, 'Child1');
    insert into Partial_Children1(attribute2, type)
      values(new.attribute2, 'Child1');
  );

محاولة إدراج البيانات مع

insert into Children1 (attribute1, attribute2)
  values ('a1', 'a2'),
         ('b1', 'b2');

تعطي رسالة الخطأ

ERROR:  insert or update on table "partial_children1" violates foreign key constraint "partial_children1_id_fkey"
DETAIL:  Key (id,type)=(3,Child1) is not present in table "parents".

طريقة لحل هذا هو استبدال إدراج الثاني من قاعدة إعادة الكتابة

insert into Partial_Children1(id, attribute2, type)
  select p.id, new.attribute2, p.type
    from Parents p
    where p.attribute1 = new.attribute1

ولكن هذا يعتمد على تفرد السمة 1، والتي لا أريد فرضها. سيكون حل آخر لإدراج القيم أولا في جدول مؤقت، ثم لتحديد مرتين من هناك للإيرادات في الجدولين. لكنني لا أحب ذلك بسبب أسباب الأداء.

هل لدى أي شخص فكرة أخرى كيفية الحصول على نفس القيم الافتراضية في كلا الجدولين (فقط باستخدام القواعد و ليس محفزات)؟

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

المحلول

من المستنداتhttp://www.postgresql.org/docs/8.4/static/rules.html.

يقوم ذلك (نظام القاعدة) بتعديل الاستفسارات لاتخاذ القواعد في الاعتبار، ثم يمر الاستعلام المعدل إلى مخطط الاستعلام للتخطيط والتنفيذ

لذلك أولا إعادة كتابة الاستعلامات دون تنفيذ أي شيء.

يمكنك جعلها تعمل عند إدراج سجلات multipe مرة واحدة:

create or replace rule ct_i_children1 as
  on insert to Children1
  do instead (
    insert into Parents(id, attribute1, type)
      values(nextval('parents_id_seq'), new.attribute1, 'Child1');
    insert into Partial_Children1(id, attribute2, type)
      values(currval('parents_id_seq'), new.attribute2, 'Child1');
  );

ثم يمكنك القيام به:

insert into Children1 (attribute1, attribute2) values ('a1', 'a2');
insert into Children1 (attribute1, attribute2) values ('b1', 'b2');

لكن لا

insert into Children1 (attribute1, attribute2)
  values ('a1', 'a2'),
         ('b1', 'b2');

لذلك يجب عليك حقا عدم استخدام نظام القواعد مع مكالمات Craffal صعبة ().

بالإضافة إلى ذلك، نلقي نظرة على التعليقات على هذه الصفحات:

نصيحة أخرى: الدعم في القائمة البريدية postgresql هو ممتاز مثل محرك قاعدة البيانات نفسه!

وبالمناسبة: هل تعرف أن postgresql لديه دعم للميراث خارج الصندوق؟

ملخص: يجب عليك استخدام المشغلات أو تجنب إدراجات صف متعددة!

نصائح أخرى

سوف تفعل القواعد ذلك من أجلك - قاموا بإعادة كتابة الاستعلام قبل تنفيذها.

طالما أن لديك جدول فعلي للقاعدة (الأطفال 1)، أعتقد أنك ستكون قادرا على تحقيق نفس الشيء مع الزناد بدلا من قاعدة.

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