it-frosch
Goto Top

Invoke-Sqlcmd Fehler abfangen in Powershell

Hallo Powershell Coder,

Ausgangssituation:
Die User bekommen eine Powershell GUI mit zwei Textfeldern in die sie Kundennummer und Kontonummer eingeben können.
Mit dem Klick auf den Ausführen-Schalter wird eine SQL Procedure auf dem Server aufgerufen,
um bei dem Kunden die Kontonummer zu aktualisieren.
Das alles funktioniert.
Ich habe auch viele Fehler (leeres Textfelder, nicht existierende Kundennummer, "0" Eingaben, negative Zahlen) bereits abgefangen.

Zum Schluss bleibt jetzt noch übrig, dass ein User in das Textfeld "NULL" schreibt oder "asdf", warum auch immer er das tun sollte. Ich möchte es abfangen.
In einem solchen Fall bekomme ich in der Powershell so eine Meldung ausgeworfen:
Invoke-Sqlcmd : Fehler beim Konvertieren des varchar-Datentyps in int. 
 Meldung: 8114, Ebene: 16, Zustand: 5, Prozedur: SP_KONTONR_AENDERN, Zeile: 0.
In C:\#Data\OneDrive - PFAD\Datei.ps1:1384 Zeichen:29
+ ... $job10001 = Invoke-Sqlcmd  -ConnectionString "Data Source=$SqlServer; ...  
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Was ja auch korrekt ist.

Im ersten Ansatz habe ich im Powershellscript die Query Definition und den Invoke-Sqlcmd Aufruf in
TRY & CATCH verpackt.
    try
            {
                $query_10001 = "declare @info int;exec [SP_KONTONR_AENDERN] '$($textBox1.Text)','$($textBox2.Text)',@info OUTPUT;select @info as ergebnis"  
            
                $job10001 = Invoke-Sqlcmd  -ConnectionString "Data Source=$SqlServer; Initial Catalog=$Database; User Id=$SqlAuthLogin; Password =$SqlAuthPw ;Encrypt = false" -Query "$query_10001"  
            }
            catch
            {
                if ($_.FullyQualifiedErrorID -eq 'SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand')   
                    {     
                        AppendToTextBox_Red("Die Eingabe war ungültig.")  
                        $textBox1.Text=''  
                        $textBox2.Text=''  
                    } 
            }          

Leider ignoriert PS TRY & CATCH und wirft trotzdem die Meldung an die Konsole.

Im zweiten Schritt habe ich in der SQL Prozedur das Prüfen der Parameter und das Update in TRY & CATCH
gepackt.
BEGIN TRY
-- Kundennummer prüfen
IF ((ISNUMERIC(@INT_1)=0) OR (@INT_1<=0)) SET @STATUS=@STATUS+1;
-- Debitorenkontonr prüfen
IF ((ISNUMERIC(@INT_2)=0) OR (@INT_2<=0)) SET @STATUS=@STATUS+10;
-- Gültigkeit der Kundennummer prüfen
IF (select count(kundennr) from kunden where kundennr=@INT_1)=0 SET @STATUS=@STATUS+100


	IF (@STATUS=0)	update kunden set kontonr=@INT_2 where kundennr=@INT_1;

Select @STAT = @STATUS
END TRY
BEGIN CATCH
set @STATUS=11
select @STAT = @STATUS 
END CATCH

Auch das bringt keinen Erfolg.

Falls die Frage kommt so "rede ich mit dem SQL Server"
# - SQL Server Verbindung deklarieren
$SqlServer    = 'SQLSERVER\INSTANZ' # SQL Server instance (HostName\InstanceName for named instance)  
$Database     = 'DB'           # SQL database to connect to   
$SqlAuthLogin = 'gui_user'              # SQL Authentication login  
$SqlAuthPw    = 'xxxxx  # SQL Authentication login password  

Hat einer von euch dazu Ideen?
Mir widerstrebt verständlicherweise es das so rauszugeben, in der Hoffnung, dass niemand Text in die Felder eingibt. face-wink

Update
Eine zweite, wenn auch aufwendigere Lösung wäre es, in der SQL Prozedur die Parameter als varchar zu definieren und
im Update Befehl zu casten.

Grüße vom it-frosch

Content-ID: 42617263200

Url: https://administrator.de/contentid/42617263200

Ausgedruckt am: 23.11.2024 um 08:11 Uhr

8030021182
Lösung 8030021182 09.11.2023 aktualisiert um 13:58:53 Uhr
Goto Top
Hi
Die Eingaben vorher in der Powershell prüfen ...
if ($textbox1.Text.trim() -notmatch '^\d+$' -or $textbox2.Text.trim() -notmatch '^\d+$'){  
     [System.Windows.Forms.MessageBox]::Show("Fehlerhafte Eingaben (Nur Zahlen erlaubt)","Fehler",0,48)  
     return
}
Gruß Katrin
it-frosch
it-frosch 09.11.2023 aktualisiert um 14:02:19 Uhr
Goto Top
@8030021182

kannst du mir '^\d+$' erklären?
Das sind reguläre Ausdrücke, vermute ich. Damit hatte ich bisher Null Berührungen.

Ansonsten ist die Idee super.
Ich habe gerade die Parameter in der SQL Prozedur als varchar definiert und im Update gecastet.
Das funktioniert auch perfekt.

Deine Lösung gefällt mir aber besser, ich muss sie halt nur noch verstehen. :D

Das TRIM ist auch eine gute Idee. face-wink

Grüße vom it-frosch
it-frosch
it-frosch 09.11.2023 um 14:22:13 Uhr
Goto Top
@8030021182

Erklärung hat sich erledigt.

'^\d+$' -> die komplette Eingabezeite (^$) darf nur eine (+) Dezimalzahl (\d) enthalten.

Wieder etwas gelernt.

Vielen Dank katrin11.
8030021182
8030021182 09.11.2023 aktualisiert um 15:01:12 Uhr
Goto Top
Wieder etwas gelernt.
👌
Lohnt sich auswendig zu lernen, läuft einem beim Skripten immer wieder über den Weg und ist extremst nützlich: Regular Expressions