Frage

Zu allererst (falls das ist wichtig) Ich verwende Active Perl (v5.8.7 gebaut für mswin32-x86-Multi-Thread).

Ich habe gerade von einem dreistündigen Debug-Sitzung heraus, versuchen, die Quelle eines Fehlers zu finden. Ich fand es gab einfach keine Fehler, aber aus irgendeinem Grunde ADO Connection-Objekt wurde immer die Errors.Count mit jeder gedruckten Nachricht erhöhten in meiner gespeicherten Prozedur ausgegeben.

Betrachten Sie folgende Transact SQL-Code:

CREATE PROCEDURE dbo.My_Sample() AS
BEGIN TRAN my_tran
-- Does something useful
if @@error <> 0 BEGIN
  ROLLBACK TRAN my_tran
  RAISERROR( 'SP My_Sample failed', 16, 1)
END ELSE BEGIN
  COMMIT TRAN my_tran
  PRINT 'SP My_Sample succeeded'
END

Nun stellen Sie einen Perl-Unter mehr oder weniger wie:

sub execute_SQL {
  # $conn is an already opened ADO connection object
  # pointing to my SQL Server
  # $sql is the T-SQL statement to be executed
  my($conn, $sql) = @_;
  $conn->Execute($sql);
  my $error_collection = $conn->Errors();
  my $ecount = $error_collection->Count;
  if ($ecount == 0 ) { return 0; }
  print "\n" . $ecount . " errors found\n";
  print "Executed SQL Code:\n$sql\n\n";
  print "Errors while executing:\n";
  foreach my $error (in $error_collection){
    print "Error: [" . $error->{Number} . "] " . $error->{Description} . "\n";
  }
  return 1;
}

Irgendwo anders, im Haupt Perl-Code, ich rufe die obigen Unter wie:

execute_SQL( $conn, 'EXEC dbo.My_Sample' );

Am Ende habe ich es, dass alle PRINT-Anweisung wird ein neuer Pseudofehler auf die ADO-Errors-Auflistung angehängt werden. Die schnelle Lösung ich implementiert war, dass PRINT in der SP in ein SELECT, zu ändern, um dies zu umgehen.

Die Fragen Ich mag würde stellen sind:

  • Ist dieses Verhalten normal?
  • Gibt es eine Möglichkeit / Bypass zu vermeiden, ist es?
War es hilfreich?

Lösung

Dies ist zu erwarten, wie es ist, was ADO tut und die Win32 :: ADO ist eine ziemlich dünne Schicht darüber.

ref: Wissensbasis beachten Sie, dass die RAISERROR und PRINT-Anweisungen durch die ADO-Sammlung Error zurückgegeben werden

Andere Tipps

OK, nachdem ein Los der Prüfung und Lesen, ich kam es zu finden, erklärte in den Bols' Artikel "Mit PRINT" (Hervorhebung von mir):

  

Die PRINT-Anweisung wird verwendet, um Nachrichten zu Anwendungen zurückzukehren. PRINT nimmt entweder ein Zeichen oder Unicode-String-Ausdruck als Parameter und gibt die Zeichenfolge als eine Nachricht an die Anwendung. Die Nachricht wird als Informationsfehler auf Anwendungen mit dem SQLClient Namespace oder der ActiveX Data Objects (ADO), OLE DB und Open Database Connectivity (ODBC) Application Programming Interfaces (APIs) zurückgegeben. SQLSTATE wird auf 01000, die native Fehler auf 0 gesetzt wird, und die Fehlermeldung Zeichenfolge wird an die angegebene Zeichenkette in der PRINT-Anweisung gesetzt. Die Zeichenfolge wird an den Message-Handler Callback-Funktion in DB zurück -Bibliothek Anwendungen.

Mit diesem Wissen ich diesen VB6 angepasst von diesem DevX Artikel bis ich folgt aus:

sub execute_SQL {
  # $conn is an already opened ADO connection object
  # pointing to my SQL Server
  # $sql is the T-SQL statement to be executed
  # Returns 0 if no error found, 1 otherwise
  my($conn, $sql) = @_;
  $conn->Execute($sql);
  my $error_collection = $conn->Errors();
  my $ecount = $error_collection->Count;
  if ($ecount == 0 ) { return 0; }

  my ($is_message, $real_error_found);
  foreach my $error (in $error_collection){
    $is_message = ($error->{SQLState} eq "01000" && $error->{NativeError}==0);
    $real_error_found=1 unless $is_message;

    if( $is_message) {
      print "Message # " . $error->{Number}
      . "\n Text: " . $error->{Description} ."\n";
    } else {
      print "Error # " . $error->{Number}
      . "\n Description: " . $error->{Description}
      . "\nSource: " . $error->{Source} . "\n";
    }
  }

  print $message_to_print;
  return $real_error_found;
}

So, jetzt meine Perl Unter wirkliche Fehler richtig aussortiert (emittiert von SQL Server über eine RaisError) und eine gemeinsame Nachricht über „PRINT“ ausgegeben wird.

Dank Richard Harrison für seine Antwort, die mich führt auf Erfolg den Weg.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top