PL / SQL में UPDATE से प्रभावित पंक्तियों की संख्या


162

मेरे पास पीएल / एसक्यूएल फ़ंक्शन (ओरेकल 10 जी पर चल रहा है) जिसमें मैं कुछ पंक्तियों को अपडेट करता हूं। क्या यह पता लगाने का एक तरीका है कि UPDATE से कितनी पंक्तियाँ प्रभावित हुईं? क्वेरी को मैन्युअल रूप से निष्पादित करते समय यह मुझे बताता है कि कितनी पंक्तियाँ प्रभावित हुईं, मैं पीएल / एसक्यूएल में उस नंबर को प्राप्त करना चाहता हूं।

जवाबों:


245

आप sql%rowcountचर का उपयोग करें ।

आपको उस कथन के बाद इसे सीधे कॉल करने की आवश्यकता है जिसके लिए आपको प्रभावित पंक्ति गणना खोजने की आवश्यकता है।

उदाहरण के लिए:

set serveroutput ON; 
DECLARE 
    i NUMBER; 
BEGIN 
    UPDATE employees 
    SET    status = 'fired' 
    WHERE  name LIKE '%Bloggs'; 
    i := SQL%rowcount; 
    --note that assignment has to precede COMMIT
    COMMIT; 
    dbms_output.Put_line(i); 
END; 

4
और असाइनमेंट को किसी भी COMMIT से पहले करना होगा
rshdev

@Clive के साथ मुझे एक प्रक्रिया मिली है INSERT INTO.. COMMITऔर सम्मिलित करने के बाद भी उसी प्रक्रिया में, मेरे पास है UPDATE SET WHERE EXISTS..COMMIT, लेकिन मैं i := SQL%rowcount;उन पंक्तियों के बजाय सभी पंक्तियों को वापस कर रहा हूं जिन्हें केवल अपडेट किया गया था। क्या हो सकता है?
गुहिलमे माथियस

26

जो लोग एक सादे आदेश से परिणाम चाहते हैं, उनके लिए समाधान हो सकता है:

begin
  DBMS_OUTPUT.PUT_LINE(TO_Char(SQL%ROWCOUNT)||' rows affected.');
end;

मूल समस्या यह है कि SQL% ROWCOUNT एक PL / SQL चर (या फ़ंक्शन) है, और इसे सीधे SQL कमांड से एक्सेस नहीं किया जा सकता है। एक बिना नाम PL / SQL ब्लॉक का उपयोग करके, यह प्राप्त किया जा सकता है।

... अगर किसी के पास इसका चयन करने के लिए एक कमांड में उपयोग करने के लिए एक समाधान है, तो मुझे दिलचस्पी होगी।


6

वैकल्पिक रूप से, SQL%ROWCOUNT आप किसी चर को घोषित करने की आवश्यकता के बिना प्रक्रिया के भीतर इसका उपयोग कर सकते हैं


4
आप की जरूरत है - एसक्यूएल% ROWCOUNT एक समारोह, तुम बस नहीं "के लिए इसका इस्तेमाल" कर सकते हैं करते हैं इसके साथ कुछ - चाहे एक चर में संग्रहीत करने, या किसी अन्य प्रक्रिया के लिए इनपुट के रूप में यह भेजने, या कुछ और करने के लिए इसे जोड़ने।
जेफरी केम्प

8
मुझे लगता है कि अली एच का कहना है कि जब तक आप एक और एसक्यूएल स्टेटमेंट को प्रभावित नहीं करेंगे, तब तक इसे वैरिएबल में असाइन करना आवश्यक नहीं है। कहा जा रहा है, मैं सहमत हूं कि बग को पैदा करने से बचने के लिए इसे एक चर में सौंपा जाना चाहिए, बाद में किसी को किसी अन्य SQL कथन को जोड़ने से पहले जोड़ना चाहिए। और, अली एच का यह जवाब एक अलग उत्तर के रूप में पोस्ट किए जाने के बजाय क्लाइव के जवाब पर एक टिप्पणी होना चाहिए
किर्बी

1

SQL%ROWCOUNTअसाइन किए बिना भी उपयोग किया जा सकता है (कम से कम Oracle 11g से )।

जब तक कोई ऑपरेशन (अपडेट, डिलीट या इंसर्ट) चालू ब्लॉक के भीतर नहीं किया जाता है, तब तक SQL%ROWCOUNTइसे शून्य पर सेट किया जाता है। फिर यह अंतिम DML ऑपरेशन से प्रभावित लाइन की संख्या के साथ रहता है:

हम तालिका ग्राहक है

create table client (
  val_cli integer
 ,status varchar2(10)
)
/

हम इसे इस तरह से परखेंगे:

begin
  dbms_output.put_line('Value when entering the block:'||sql%rowcount);

  insert into client 
            select 1, 'void' from dual
  union all select 4, 'void' from dual
  union all select 1, 'void' from dual
  union all select 6, 'void' from dual
  union all select 10, 'void' from dual;  
  dbms_output.put_line('Number of lines affected by previous DML operation:'||sql%rowcount);

  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      elsif sql%rowcount = 1 then
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
      else -- >1
        dbms_output.put_line(sql%rowcount||' clients updated for '||val);
      end if;
  end loop;  
end;

जिसके परिणामस्वरूप:

Value when entering the block:
Number of lines affected by previous DML operation:5
2 clients updated for 1
no client with 2 val_cli.
no client with 3 val_cli.
1 client updated for 4
no client with 5 val_cli.
1 client updated for 6
no client with 7 val_cli.
no client with 8 val_cli.
no client with 9 val_cli.
1 client updated for 10

-1

कृपया इसे आजमाएं..


create table client (
  val_cli integer
 ,status varchar2(10)
);

---------------------
begin
insert into client
select 1, 'void' from dual
union all
select 4, 'void' from dual
union all
select 1, 'void' from dual
union all
select 6, 'void' from dual
union all
select 10, 'void' from dual;
end;

---------------------
select * from client;

---------------------
declare
  counter integer := 0;
begin
  for val in 1..10
    loop
      update client set status = 'updated' where val_cli = val;
      if sql%rowcount = 0 then
        dbms_output.put_line('no client with '||val||' val_cli.');
      else
        dbms_output.put_line(sql%rowcount||' client updated for '||val);
        counter := counter + sql%rowcount;
      end if;
  end loop;
   dbms_output.put_line('Number of total lines affected update operation: '||counter);
end;

---------------------
select * from client;

--------------------------------------------------------

परिणाम निम्नानुसार होगा:


2 ग्राहक
2 val_cli के साथ 1 ग्राहक के लिए अपडेट किया गया ।
3 val_cli के साथ कोई क्लाइंट नहीं।
1 ग्राहक
5 val_cli के साथ 4 नहीं क्लाइंट के लिए अपडेट किया गया ।
1 ग्राहक
7 val_cli के साथ 6 नो क्लाइंट के लिए अपडेट किया गया ।
8 val_cli के साथ कोई क्लाइंट नहीं।
9 val_cli के साथ कोई क्लाइंट नहीं।
1 क्लाइंट 10
लाइनों के लिए अपडेट किया गया , कुल लाइन प्रभावित अपडेट ऑपरेशन: 5



अपने समाधान में टिप्पणी जोड़ें, कृपया विशिष्ट बनें।
कुमार अभिषेक

-3

काउंट (*) एनालिटिकल फंक्शन OVER PARTITION by NULL का उपयोग करें यह कुल पंक्तियों की # गिनती करेगा


यदि आप वास्तव में अपडेट किए गए पर गिनती की जाँच करते हैं तो अपडेट स्टेटमेंट चलाने के बाद - यह कोई सामान्य समाधान नहीं देता है। उदाहरण के लिए, यदि मेरी तालिका T में एक स्तंभ c1 है, जिसमें सभी के लिए मान के रूप में "1" है और अब मैं उस स्तंभ के लिए सभी पंक्तियों को "2" में अपडेट कर देता हूं, तो शून्य सहायता से विभाजन कैसे होगा?
नैनोसॉफ्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.