Announcement

Collapse
No announcement yet.

Procedure: Ungültige Referenz auf Variable 'xxx'

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Procedure: Ungültige Referenz auf Variable 'xxx'

    Hallo,

    meine Procedure bringe ich nicht zu laufen.
    Die Proc soll prüfen, ob eine Tabelle existiert und wenn ja dann löschen.
    Wer kann mir helfen.
    Danke.
    Reinhold P.

    ERROR at line 9: PLS-00487: Ungültige Referenz auf Variable 'ASCHEMNAME'
    7.
    8. if TabAnz > 0 then begin
    9. execute immediate 'drop table' + aSchemName.aTabName; exception when others then null; end;
    10. end if;
    11. commit;



    Code:
    create or replace procedure asDropTableIfExists(aTabName in VarChar2, aSchemName in VarChar2) is
    TabAnz Number;
    begin
      select count(*) into TabAnz 
      from all_tables 
      where TABLE_NAME = aTabName and OWNER = aSchemName; 
      
      if TabAnz > 0 then begin
        execute immediate 'drop table' + aSchemName.aTabName; exception when others then null; end;
      end if;
      commit;
       
    end asDropTableIfExists;

  • #2
    Hi,

    Du hast zwei dicke Hunde drinnen:
    1.
    Code:
     exception when others then null;
    Egal welcher Fehler auftritt, Du ignorierst ihn vollständig. Das nenn ich mal ein robustes Programm.

    2.
    Code:
     + aSchemName.aTabName;
    Stringconcartinierung wird in PL/SQL mit || oder der Funktion CONCAT gemacht. Des weiteren baust Du den Schema/Tabellennamen falsch zusammen.
    Das muss so aussehen:
    Code:
     execute immediate 'drop table' || aSchemName||'.'||aTabName;
    Dim
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #3
      Procedure: Ungültige Referenz auf Variable 'xxx'

      Hallo dimitri,

      danke jetzt läufts. Habe beide Punkte korrigiert.
      Reinhold P.

      Hier die vollständige Procedure:
      Code:
      create or replace procedure asDropTableIfExists(aTabName in VarChar2, aSchemName in VarChar2) is
      TabAnz Number;
      begin
        select count(*) into TabAnz 
        from all_tables 
        where TABLE_NAME = aTabName and OWNER = aSchemName; 
        
        if TabAnz > 0 then begin
          execute immediate 'drop table' || aSchemName||'.'||aTabName; end;
        end if;
        commit;
         
      end asDropTableIfExists;

      Comment


      • #4
        danke jetzt läufts.
        Kann ich mir fast nicht vorstellen. Du hast nämlich den gleichen Fehler wie ich gemacht

        execute immediate 'drop table' || aSchemName||'.'||aTabName; end;
        Was fehlt? Ein Blank nach table natürlich.

        Dim
        Zitat Tom Kyte:
        I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

        Comment


        • #5
          Procedure: Ungültige Referenz auf Variable 'xxx'

          Hallo Dimiri,

          stimmt, es war kompilierbar, aber nicht lauffähig. Das Blank hinter drop table hat gefehlt.

          Weitere Frage:
          Beide Code-Teile laufen einzeln, aber nicht nacheinander. Warum?
          Reinhold P.

          Fehler:
          ORA-06550: Zeile 7, Spalte 1:
          PLS-00103: Fand das Symbol "CREATE"


          Code:
          ---Teil 1: Tables löschen falls vorhanden
          begin
            asdroptableifexists(ATABNAME => 'T_Table1', aschemname => 'MySchema');
          end;
          
          --- Teil 2: Tables anlegen
          Create Table Table1(
             MyID     NUMBER(10,0)                    NOT NULL);

          Comment


          • #6
            Du kannst in PL/SQL kein DDL ausführen. Das musst Du immer über execute immediate machen.


            Dim
            Zitat Tom Kyte:
            I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

            Comment


            • #7
              Danke!

              Hallo Dimitri,

              ich werde es getrennt lassen (müssen).

              Danke für die Unterstützung.

              Reinhold P.

              Comment


              • #8
                Hallo,

                versuchs mal so:

                Originally posted by Reinhold_P View Post
                Code:
                ---Teil 1: Tables löschen falls vorhanden
                begin
                  asdroptableifexists(ATABNAME => 'T_Table1', aschemname => 'MySchema');
                end;
                /
                --- Teil 2: Tables anlegen
                Create Table Table1(
                   MyID     NUMBER(10,0)                    NOT NULL);
                Grüße

                Logan2012

                http://www.dbplace.de

                Comment


                • #9
                  Danke!

                  Hallo logan2012,

                  Mit dem '/' läuft's jetzt auch in einer Datei. Super!

                  (Aber was bewirkt der '/' ?)

                  Reinhold

                  Comment


                  • #10
                    Hallo Reinhold,

                    ich kann im Augenblick keine ausformulierte Erklärung liefern, aber es verhält sich so:

                    Mit einen Begin leitet man einen sogenanten anonymous block ein. Dieser wird im PL/SQL abgearbeitet. Nach dem PL/SQL -Block kommt auf einmal wieder SQL. Das muß der Datenbank durch ein / mitgeteilt werden.

                    Robert
                    Grüße

                    Logan2012

                    http://www.dbplace.de

                    Comment


                    • #11
                      Hallo Reinhold,

                      so wie es scheint, arbeitest Du mit SQL*Plus. Darin hat der '/' folgende Bedeutung:
                      Er führt das SQL im SQL-Puffer ohne vorherige Anzeige aus.
                      Bedeutet:
                      Wenn du einen anonymen Block schreibst - in Deinem Fall beginn ... end - wird dieser im SQL-Puffer abgelegt.
                      Ohne '/' wird die weitere Eingabe ebenfalls in den Puffer geschrieben und da kommt es dann zu dem von Dimitri beschriebenen Konflikt - da durch dass beginn ein anonymer PL/SQL-Block eingeleitet wurde wird alles im Puffer als PL/SQL behandelt.
                      Durch das '/' wird der Block im Puffer ausgeführt und der Pufferinhalt gelöscht. Danach füllst Du den Puffer mit einem 'normalen' - sprich einzeiligem - Statement und dabei ist kein '/' zur Ausführung notwendig.

                      Ich hoffe ich konnte es Dir einigermaßen erklären.

                      Gruß
                      Albernd

                      Comment

                      Working...
                      X