Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

shrink space

Dieses Thema im Forum "Oracle" wurde erstellt von f_mal, 13 März 2017.

  1. f_mal

    f_mal Benutzer

    Hallo Zusammen,

    ich bekomme eine Fehlermeldung beim ausführen dieser Code:
    Code:
    DECLARE
      cursor c_idx IS
        SELECT index_name
        FROM   USER_INDEXES
        WHERE  tablespace_name = 'xxx';
    BEGIN
      FOR rec IN c_idx LOOP
         EXECUTE IMMEDIATE SELECT 'ALTER TABLE '||TABLE_NAME|| ' shrink space;' FROM USER_TABLES;
      END LOOP;
    END;
    ORA-06550: Zeile 9, Spalte 3:
    PLS-00103: Fand das Symbol "END"
    06550. 00000 - "line %s, column %s:\n%s"
    *Cause: Usually a PL/SQL compilation error.
    *Action:

    Hat jemand eine Idee bitte.

    Vielen Dank im Voraus
    VG
    Flo
     
  2. unficyp

    unficyp Fleissiger Benutzer

    execute immediate 'alter table '||table_name|| shrink space';
     
  3. drdimitri

    drdimitri Datenbank-Guru

    Da ist ja alles falsch.
    Du selektierst die Indexnamen, möchtest aber den Tabellennamen, verwendest die FOR Schleife nicht richtig, Row Movement ist vermutlich nicht aktiv und das execute immediate weiß auch nicht ganz was es von Deinem Befehl halten soll.
    Was genau beabsichtigst Du denn zu machen?
     
  4. f_mal

    f_mal Benutzer

    Vielen Dank erstmal für das Feedback.

    Stimmt, ich habe mich etwas verschrieben. Es funktioniert aber immer noch nicht.
    es soll "shrink space" auf alle Tabellen des Users gemacht werden.

    DECLARE
    cursor c_tbl IS
    SELECT TABLE_NAME
    FROM USER_TABLES
    WHERE tablespace_name = 'tbs_name';
    BEGIN
    FOR rec IN c_tbl LOOP
    execute immediate 'alter table '||c_tbl|| 'shrink space';
    --dbms_output.put_line(c_tbl);
    END LOOP;
    END;

    Vielen Dank im Voraus.
    VG
    Flo
     
  5. f_mal

    f_mal Benutzer

    jetzt sieht so aus:
    DECLARE
    cursor c_tbl IS
    SELECT TABLE_NAME
    FROM USER_TABLES
    WHERE tablespace_name = 'tbs_name';
    BEGIN
    FOR rec IN c_tbl
    LOOP
    execute immediate 'alter table '||rec.TABLE_NAME|| ' enable row movement';
    execute immediate 'alter table '||rec.TABLE_NAME|| ' shrink space';
    dbms_output.put_line(rec.TABLE_NAME);
    END LOOP;
    END;

    Fehlerbericht -
    ORA-10631: SHRINK clause should not be specified for this object
    ORA-06512: in Zeile 10
    10631. 00000 - "SHRINK clause should not be specified for this object"
    *Cause: It is incorrect to issue shrink on the object
    *Action: Verify the object name and type and reissue the command
     
  6. unficyp

    unficyp Fleissiger Benutzer

  7. f_mal

    f_mal Benutzer

    Hallo und vielen Dank für die schnelle Antwort.

    jetzt sieht das ganze so aus:
    BEGIN
    FOR i IN
    (SELECT obj.owner ,
    obj.table_name ,
    (
    CASE
    WHEN NVL(idx.cnt, 0) < 1
    THEN 'Y'
    ELSE 'N'
    END) AS shrinkable
    FROM dba_tables obj,
    (SELECT table_name,
    COUNT(rownum) cnt
    FROM dba_indexes
    WHERE index_type LIKE 'FUN%'
    GROUP BY table_name
    ) idx
    WHERE obj.table_name = idx.table_name(+)
    AND obj.tablespace_name = upper('&1')
    AND NVL(idx.cnt,0) < 1
    )
    LOOP
    DBMS_OUTPUT.PUT_LINE(i.owner || ' '|| i.table_name);
    EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' enable row movement';
    EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' shrink space';
    EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' disable row movement';
    END LOOP;
    END;

    leider bekomme ich immer noch eine Fehlermeldung:
    Fehlerbericht -
    ORA-10631: SHRINK clause should not be specified for this object
    ORA-06512: in Zeile 25
    10631. 00000 - "SHRINK clause should not be specified for this object"
    *Cause: It is incorrect to issue shrink on the object
    *Action: Verify the object name and type and reissue the command

    Die Abfrage liefert aber nur die nicht Funktion Basierten aus. Ich verstehe dann nicht warum nicht durchläuft.
    Weitere Ideen?

    VG
    Flo
     
  8. drdimitri

    drdimitri Datenbank-Guru

    Mach doch mal ne Fehlerbehandlung rein:
    Code:
    declare
    ...
    begin
    loop
      begin
       ...
      exception when others then
       dbms_output.put_line(SQLERRM|| ' Name der Tabelle etc.');
      end;
    end loop;
    end;
    
    In sqlplus ein set serveroutput on
    In Toad, Sql Dev o.ä. per entsprechenden Button aktivieren.
    Dann schau dir mal die Tabellen an.
     
  9. f_mal

    f_mal Benutzer

    kann ich irgendwie Fehler ignorieren und weitermachen, so dass die Procedure zu ende läuft. Es soll nur da ein SHRINK gemacht werden, wo es geht. Alles andere soll übersprungen werden.

    VG
    Flo
     
  10. drdimitri

    drdimitri Datenbank-Guru

    Das macht mein Vorschlag. Der läuft durch egal was passiert.
     
  11. f_mal

    f_mal Benutzer

    DANKE. So sieht im Moment aus. Es läuft aber nicht durch:

    Code:
    BEGIN
      FOR i IN
      (SELECT obj.owner ,
        obj.table_name ,
        (
        CASE
          WHEN NVL(idx.cnt, 0) < 1
          THEN 'Y'
          ELSE 'N'
        END) AS shrinkable
      FROM dba_tables obj,
        (SELECT table_name,
          COUNT(rownum) cnt
        FROM dba_indexes
        WHERE index_type LIKE 'FUN%'
        GROUP BY table_name
        ) idx
      WHERE obj.table_name    = idx.table_name(+)
      AND obj.tablespace_name = upper('&1')
      AND NVL(idx.cnt,0)      < 1
      )
      LOOP
        DBMS_OUTPUT.PUT_LINE(i.owner || '  '|| i.table_name);
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' enable row movement';
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' shrink space cascade';
        dbms_output.put_line(SQLERRM    ||i.owner||'.'||i.table_name);
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' disable row movement';
      END LOOP;
    END;
    Was mache ich falsch?
    VG
    Flo
     
  12. f_mal

    f_mal Benutzer

    also... jetzt scheint zu funktionieren:

    Code:
    BEGIN
      FOR i IN
      (SELECT obj.owner ,
        obj.table_name ,
        (
        CASE
          WHEN NVL(idx.cnt, 0) < 1
          THEN 'Y'
          ELSE 'N'
        END) AS shrinkable
      FROM dba_tables obj,
        (SELECT table_name,
          COUNT(rownum) cnt
        FROM dba_indexes
        WHERE index_type LIKE 'FUN%'
        GROUP BY table_name
        ) idx
      WHERE obj.table_name    = idx.table_name(+)
      AND obj.tablespace_name = upper('&1')
      AND NVL(idx.cnt,0)      < 1
      )
      LOOP
      BEGIN
        DBMS_OUTPUT.PUT_LINE(i.owner || '  '|| i.table_name);
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' enable row movement';
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' shrink space cascade';
        dbms_output.put_line(SQLERRM    ||i.owner||'.'||i.table_name);
        EXECUTE immediate 'alter TABLE '||i.owner||'.'||i.table_name||' disable row movement';
        exception when others then
         dbms_output.put_line(SQLERRM    ||i.owner||'.'||i.table_name);
      END;
      END LOOP;
    END;
    Vielen Dank für eure Unterstützung.

    VG
    Flo
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden