shrink space

f_mal

Benutzer
Beiträge
9
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
 
Werbung:
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?
 
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
 
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
 
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
 
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.
 
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
 
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
 
Werbung:
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
 
Zurück
Oben