Announcement

Collapse
No announcement yet.

Fehler PLS-00306

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

  • Fehler PLS-00306

    Hallo

    Ich habe folgendes Problem:

    In einem Perl-Skript, rufe ich eine Stored Procedure auf, welche überprüft, ob eine Datei bereits in der Datenbank existiert.

    Existiert die Datei bereits, läuft das Skript ohne Probleme durch.

    Existiert die Datei jedoch nicht, erhalte ich folgenden Fehler:

    DBD::Oracle::st execute failed: ORA-06550: line 4, column 8:
    PLS-00306: wrong number or types of arguments in call to 'CS_CHECK_VOICE_DOC_EXISTS'

    Der Mitgabewert aus dem Perl-Skript ist jedoch immer gleich aufgebaut. Halt eben eine andere Nummer, aber sonst gleich.

    irgend jemand eine Ahnung?

    Wenn skript-Ausschnitte benötigt werden, bitte sagen...

    Danke im Voraus

  • #2
    Wenn skript-Ausschnitte benötigt werden, bitte sagen...
    Ich würde gerne den betreffenen PL/SQL Code sehen, sowie den Aufruf

    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
      Perl Aufruf:

      Code:
      				   my $func2 = $dbh->prepare(q{
      						BEGIN
      							if
      							sysadm.cs_adresse_test.cs_check_voice_doc_exists(
      							parameter1_in => :parameter1
      							);
      						then
      							:rv := dbms_output.put_line('2');
      						else
      							:rv := dbms_output.put_line('3');
      						end if;
      							END;
      							}
      					); 
      					$func2->bind_param(":parameter1", \$basename, {TYPE => SQL_CHAR} );
      					$func2->bind_param_inout(":rv", \$rv, 2, {TYPE => SQL_INTEGER});
      					$func2->execute;


      PL/SQL:

      Code:
      create or replace package cs_adresse_test is
      
        -- #99045922#
        function cs_check_voice_doc_exists(i_vr_doc in ps_cs_sperrlog_tb.cs_voice_doc%type) return integer;
      
      
      
      end cs_adresse_test;
      
      
      create or replace package body cs_adresse_test is
      
         function cs_check_voice_doc_exists(i_vr_doc ps_cs_sperrlog_tb.cs_voice_doc%type) return integer is
          l_dummy_string ps_cs_sperrlog_tb.cs_voice_doc%type;
        begin
          --
          select a.cs_voice_doc
            into l_dummy_string
            from ps_cs_sperrlog_au a
           where a.cs_voice_doc = i_vr_doc
             and rownum = 1;
        
          return(2);
        
        exception
          when no_data_found then
            return(3);
          when too_many_rows then
            return(2);
          when others then
            return(2);
        end;
        
      end cs_adresse_test;
      Mitlerweile hab ichs noch ein bisschen umgeschrieben.
      Dennoch, bei in der DB vorhandenen Dateien, läuft das Skript sauber durch.
      Bei in der DB nicht vorhandenen Dateien, kommt folgende Meldung:
      Code:
      Can't bind a reference (SCALAR(0x8cd6e6c))
      (mit Referenz auf die Zeile wo "bind_param" für : parameter1 ist...

      Comment


      • #4
        Also ich vermute eher, dass Du einen falschen Wert übergibst z.B. einen Buchstaben und der kann nicht in eine Zahl konvertiert werden.
        Zum Packageaufruf kommt es nämlich überhaupt nicht.

        Welchen Datentyp hat denn ps_cs_sperrlog_tb.cs_voice_doc?

        Des weiteren solltest Du dringend den WHEN OTHERS Block rausnehmen, denn damit verschluckst Du alle möglichen Fehler und gehst anschließend im Programm davon aus, dass es mindestens einen Eintrag gibt.

        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
          Du meinst das Perl Script übergibt einen falschen Wert?

          also, Parameter1 enthält immer einen Wert, der wie folgt aussieht (Zahlen variieren):
          Code:
          CRM_00000000000010652923_GENERELL_20100804_131500
          Gibt es den Eintrag, kommt keine Fehlermeldung, existiert kein Eintrag,... Can't bind...

          Wieso geht es denn, wenn der Eintrag existiert? Wenn es ein falscher Wert wäre, würde er ja immer auf die Schnauze fliegen oder?

          Das when other, haben wir eingebaut, damit in jedem Fall ein Wert zurück kommt, da wir nicht genau wussten, ob es daran liegt...

          Comment


          • #6
            Was ist, wenn ich einfach die Stored Procedure rauslasse, und mit dem Script direkt zugreiffe:

            Code:
            				   my $sql = qq{ SELECT a.cs_voice_doc FROM 'ps_cs_sperrlog_au a' WHERE a.cs_voice_doc = $basename };
            				   
            				   my $func = $dbh->prepare( $sql ) || die $dbh->errstr; 
            	
            					$func->execute;
            					
            					my ( $exists, $undef );
            					
            					$func->bind_columns( \$exists, \$undef );
            
            										
            					
            					if ( $exists = '' ) { #present in that hidden view, we need to archive it
            										
            					# kill the COMMANDS file
            					unlink($extdir."/".$basename."/COMMANDS");
            					#delete the actual VR file					
            					unlink($extdir."/".$basename."/".$filename);
            					#delete the whole directory - rmdir() needs a squeaky clean directory
            					rmdir($extdir."/".$basename);
            					#delete the original file
            					unlink($subdir."/".$filename);
            						
            				    } 
            
            					if ( $exists != '' ) {
            					my $rawdate = @filenamecomps[3];
            					my $rawyear = substr($rawdate,0,4);
            					my $rawmonth = substr($rawdate,4,2);
            					my $rawday = substr($rawdate,6,2);
            					$oldarchdate = $rawday.".".$rawmonth.".".$rawyear;
            					}; #we have a file we really need to archive.
            
            					$func->finish();
            Was meinst du?

            PS: schon mal vielen Dank für deine Hilfe!! Bin schon seit 2tagen nicht vom Fleck gekommen...

            Comment


            • #7
              Der Bind passiert hier:
              Code:
              sysadm.cs_adresse_test.cs_check_voice_doc_exists(
                                          parameter1_in => :parameter1
              Versuch doch mal den übergebenen Parameter der beim Fehlerfall übergeben wird direkt in dein SQL Statement einzubinden und über SQL Developer, Toad etc loszuschicken was dann passiert.

              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


              • #8
                Haben wir bereits versucht, und so erhält korrekterweise den Return Wert 3, wie im PL/SQL definiert...

                mit der Überlegung die stored procedure zu umgehen, sollte es wohl klappen, was meinste?
                Zuletzt editiert von rioc; 04.08.2010, 16:00.

                Comment


                • #9
                  Ok, jetzt blicke ich bald gar nicht mehr durch...

                  Habe nun die Stored procedure umgangen, wie ein paar posts weiter oben zu sehen...

                  Folgendes Ergebnis:

                  Bei existierendem Eintrag:
                  Code:
                  Docid found : aamrfvndi1uuwsungebkgfs3aqiky
                  docid defined
                  Bei nicht vorhandenem Eintrag:
                  Code:
                  DBD::Oracle::db prepare failed: ORA-00903: invalid table name (DBD ERROR: OCIStm
                  tExecute/Describe) [for Statement " SELECT a.cs_voice_doc FROM 'ps_cs_sperrlog_a
                  u a' WHERE a.cs_voice_doc = 'CRM_00000000000010652923_GENERELL_20100804_160029'
                  "] at *** Line 288
                  Kannst du mir erklären wie das geht? Vielleicht setze ich auch meinen Denkansatz völlig falsch an...

                  Comment


                  • #10
                    Eines ist mir noch auffgefallen:
                    Ihr verwendet den Typ der Spalte ps_cs_sperrlog_tb.cs_voice_doc im PL/SQL selektiert dann aber auf die Spalte cs_voice_doc der Tabelle ps_cs_sperrlog_au. Damit habt ihr evtl. unterschiedliche Längen, die den Bind fehlschlagen lassen können.

                    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


                    • #11
                      In tb und in au stehen dieselben werte drin. tb ist einfach aktuell, au sind historische Werte...


                      Leider bin ich mit Querys in Perl etwas eingerostet, escape ich die Variabeln hier überhaupt richtig?
                      Code:
                      my $sql = qq{ SELECT '1' INTO '$dummy' FROM ps_cs_sperrlog_au WHERE cs_voice_doc = '$basename' };
                      Vorallem begreiff ich beim besten Willen nicht, wieso er bei vorhandenen Einträgen sauber durchläuft, und ansonsten mit
                      Code:
                      DBD::Oracle::db prepare failed: ORA-00942: table or view does not exist (DBD ERROR: OCIStmtExecute/Describe)
                      hinfällt...


                      Und noch was, wohl etwas einfacher:
                      Ich habe das Gefühl, dass er beim Query, nach "INTO" die Variabel $dummy ausliest, und nicht das Ergebnis in diese Variabel reinschreibt. Wie kann ich mir dessen sicher sein?
                      $dummy wird vor dem Query im Perl Script initialisiert...
                      Zuletzt editiert von rioc; 04.08.2010, 17:28.

                      Comment


                      • #12
                        ARGH, bin derb eingerostet, müsste ich ja per fetchrow oder ähnliches tun.
                        Jedoch kann ich diese Methode mit dem direkten Query vergessen, da der Identifyer deutlich über 31 Zeichen ist.

                        Also bin ich wieder bei dem Problem:
                        Can't bind a reference (SCALAR(0x8cd6d04))

                        Woher kommt dieser Fehler? Brauche dringend Hilfe :S

                        Comment


                        • #13
                          Dazu kenn ich Perl jetzt wieder zu wenig. Was ich bisher gesehen habe sollte eigentlich laufen. hast Du die aktuelle Version des Treibers? Evtl. gibt es dort einen Bug?

                          Was passiert, wenn Du einfach einen COUNT(*) in der Procedur machst?
                          Also:
                          Code:
                          select count(*) into ... from ... where ... and rownum=1
                          Damit bekommst Du immer ein Ergebnis 1 oder 0 zurück.

                          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

                          Working...
                          X