কেন আমি ট্রিগারটিতে পরিবর্তনের টেবিল ত্রুটি পাচ্ছি না?


11

এটি (বা কমপক্ষে ছিল) জানা গেছে যে আপনি ট্রিগারের অভ্যন্তরে কোনও মিউটেশন টেবিলটিতে ডিএমএল স্টেটমেন্ট ব্যবহার করতে পারবেন না। থেকে একটি উদ্ধৃতাংশ ওরাকল ডকুমেন্টেশন :

পরিবর্তনীয় টেবিলটি এমন একটি টেবিল যা কোনও আপডেট, ডিলিট বা INSERT বিবৃতি দ্বারা সংশোধন করা হচ্ছে বা একটি সারণী যা মুছে ফেলা ক্যাসকেডের সীমাবদ্ধতার প্রভাব দ্বারা আপডেট করা যেতে পারে।

যে সেশনটি ট্রিগার স্টেটমেন্ট জারি করেছে তা কোনও মিউটেশন টেবিলকে জিজ্ঞাসা বা সংশোধন করতে পারে না। এই সীমাবদ্ধতা ডেটার অসঙ্গতিপূর্ণ সেট দেখে ট্রিগারকে বাধা দেয়।

তবে, আমি বুঝতে পারি না যে insert into empএসকিউএল বিকাশকারী বা এসকিউএল * প্লাস ব্যবহার করার সময় এই ডেমো ট্রিগারটি "মিউটটিং টেবিল" ত্রুটির সাথে কেন ব্যর্থ হচ্ছে না :

CREATE OR REPLACE TRIGGER emp_bri   
  BEFORE INSERT ON emp 
    FOR EACH ROW
BEGIN

  SELECT max(id) + 1 INTO :NEW.id FROM emp;
  UPDATE emp SET salary = 5000;

END emp_bri;

সন্নিবেশটি পরবর্তী idমান সহ সফলভাবে সম্পূর্ণ করে এবং সমস্ত empরেকর্ড আপডেট করে । আমি ওরাকল ডেটাবেস 11 জি এন্টারপ্রাইজ সংস্করণ প্রকাশ 11.2.0.1.0 ব্যবহার করছি। আমি যৌগিক ট্রিগারগুলি সম্পর্কে পড়েছি কিন্তু নমুনা সেগুলি ব্যবহার করে না।


1
আপনার প্রশ্নের সাথে সম্পর্কিত নয়, তবে: স্বতন্ত্র সংখ্যা নির্ধারণের জন্য ব্যবহার করবেন নাselect max(id) । শুধু না। এটি কেবল ভুল এবং এটিও স্কেল করবে না।
a_horse_with_no_name

হ্যাঁ, আমি জানি যে :) এই ক্ষেত্রে উদাহরণটি সম্ভবত খুব ভাল নয় ... স্বতঃসংশোধের মানগুলি অবশ্যই সিকোয়েন্স এবং ট্রিগার ব্যবহার করে প্রয়োগ করা উচিত।
সেঞ্চুরিয়ান

এটি নিশ্চিত আজব। বিটিডব্লিউ: এখানে একটি এসকিউএলফিডাল উদাহরণ রয়েছে sqlfiddle.com/#!4/9e59f/2
a_horse_with_no_name

তথ্য ভাগ করে নেওয়ার জন্য ধন্যবাদ, দুর্দান্ত লিঙ্ক। এই জাতীয় ওরাকল এসকিউএল পরীক্ষার ওয়েবসাইটটি কী তা জানা ছিল না :)
সেঞ্চুরিয়ান

a_horse_with_no_name: আরেকটি উদাহরণ: ফিডাল -পরীক্ষা -২ (SET বেতন = বেতন + 10)
ypercubeᵀᴹ

উত্তর:


12

একটি ব্যতিক্রম আছে। আপনি যখন before insertকোনও টেবিলে একটি , সারি-স্তরের ট্রিগার সংজ্ঞায়িত করেন এবং একটি একক সারির INSERTবিবৃতি দেন, table is mutatingত্রুটি উত্থাপিত হবে না। তবে আপনি যদি একই ধরণের ট্রিগার সংজ্ঞায়িত করেন এবং একটি বহু-সারি INSERTবিবৃতি দেন, ত্রুটি উত্থাপিত হবে। এখানে একটি উদাহরণ:

SQL> create table TB_TR_TEST(
  2    col1 number,
  3    col2 number
  4  )
  5  ;

Table created

SQL> create or replace trigger TR_TB_TR_TEST
  2  before insert on TB_TR_TEST
  3  for each row
  4  begin
  5    SELECT max(col1) + 1 INTO :NEW.col1
  6      FROM TB_TR_TEST;
  7    UPDATE TB_TR_TEST SET col2 = 5000;
  8  end;
  9  /

Trigger created

এখানে একটি একক-সারি insertবিবৃতি দেওয়া হয়েছে, যা পরিবর্তনের টেবিল ত্রুটি বাড়িয়ে তুলবে না:

SQL> insert into TB_TR_TEST(col1, col2) values(1,2);

1 row inserted

SQL> insert into TB_TR_TEST(col1, col2) values(3,5);

1 row inserted

SQL> commit;

Commit complete

এখানে একটি বহু-সারি সন্নিবেশ বিবৃতি দেওয়া হয়েছে, যা পরিবর্তনের টেবিল ত্রুটি বাড়িয়ে তুলবে:

SQL> insert into TB_TR_TEST(col1, col2)
  2    select 1, 2
  3      from dual;

insert into TB_TR_TEST(col1, col2)
  select 1, 2
    from dual

ORA-04091: table HR.TB_TR_TEST is mutating, trigger/function may not see it
ORA-06512: at "HR.TR_TB_TR_TEST", line 2
ORA-04088: error during execution of trigger 'HR.TR_TB_TR_TEST'

এটা অপরাধী বলে মনে হয় না। এই আচরণের জন্য ম্যানুয়ালটিতে আপনার কি কোনও উল্লেখ রয়েছে?
a_horse_with_no_name

@a_horse_with_no_name আপনার যদি সাপোর্ট.ওরাকল.কম.এ অ্যাক্সেস থাকে তবে ID 132569.1( ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement) সন্ধান করুন।
নিকোলাস ক্র্যাসনভ

2
ধন্যবাদ। যথেষ্ট ব্যতিক্রমী এই ব্যতিক্রমটি 8i (!) ম্যানুয়ালগুলিতে কেবলমাত্র নথিবদ্ধ বলে মনে হচ্ছে: ডকস.অরাকল.com / cd / F49540_01 / DOC / server.815 / a68003/… (বিভাগ " " "রূপান্তরকরণ এবং সারণি সংবিধান ") আমি করতে পারি বর্তমানের ম্যানুয়ালগুলিতে সে বিবৃতিটি খুঁজে পাবেন না
a_horse_with_no_name
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.