Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Unerwarteter Variablentyp, der von Receive-Job zurückgegeben wurde

  1. Gibt es eine Möglichkeit, den korrekten/erwarteten Variablentyp zurückzugeben, wenn Receive-Job aufgerufen wird ?

Aufgrund der Verwendung eines Hintergrundjobs verlieren Sie die Typtreue :Die Objekte, die Sie zurückerhalten, sind methodenlose Emulationen der ursprünglichen Typen.

Das manuelle Nachbauen der Originaltypen ist den Aufwand nicht wert und möglicherweise gar nicht möglich - obwohl vielleicht das Arbeiten mit den Emulationen ausreicht.

Aktualisieren :Wechseln Sie gemäß Ihrer eigenen Antwort von der Arbeit mit System.DataSet zu System.DataTable führte zu brauchbaren Emulationen für Sie.

Weitere Informationen finden Sie im unteren Abschnitt.

  1. Gibt es eine bessere Möglichkeit, SQL-Abfragen mit dem Befehl Invoke-Sqlcmd unter einem anderen AD-Konto auszuführen?

Sie benötigen eine in Bearbeitung Aufrufmethode, um die Typtreue zu wahren , aber ich glaube nicht, dass dies mit beliebigen Befehlen möglich ist, wenn Sie sich als ein anderer Benutzer ausgeben möchten .

Beispielsweise die prozessinterne (threadbasierte) Alternative zu Start-Job - Start-ThreadJob - hat kein -Credential Parameter.

Am besten versuchen Sie daher, Invoke-SqlCmd zu erstellen -Credential von Parameter für Sie arbeiten oder eine andere In-Process-Methode finden, um Ihre Abfragen mit den Anmeldeinformationen eines bestimmten Benutzers auszuführen.

Serialisierung und Deserialisierung von Objekten in Hintergrundjobs / Remoting / Mini-Shells:

Wann immer PowerShell Objekte über Prozessgrenzen hinweg marshallt verwendet es XML-basierte Serialisierung an der Quelle und Deserialisierung am Ziel , wobei ein Format verwendet wird, das als CLI XML bekannt ist (Common Language Infrastructure XML).

Dies geschieht im Zusammenhang mit PowerShell-Remoting (zB Invoke-Command Aufrufe mit dem
-ComputerName Parameter) sowie in Hintergrundjobs (Start-Job ) und sogenannte Mini-Shells (die implizit verwendet werden, wenn Sie die PowerShell-CLI innerhalb von PowerShell selbst mit einem Skriptblock aufrufen; B. powershell.exe { Get-Item / } ).

Diese Deserialisierung behält die Typtreue bei nur für eine begrenzte Menge bekannter Typen , wie in MS-PSRP, der PowerShell Remoting Protocol Specification, angegeben. Das heißt, nur Instanzen eines festen Satzes von Typen werden als ihr ursprünglicher Typ deserialisiert .

Instanzen aller anderen Typen werden emuliert :Listenartige Typen werden zu [System.Collections.ArrayList] Instanzen werden Dictionary-Typen zu [hasthable] Instanzen und andere Typen werden zu methodenlosen (nur Eigenschaften) benutzerdefinierten Objekten ([pscustomobject] Instanzen) , dessen .pstypenames -Eigenschaft enthält den ursprünglichen Typnamen mit dem Präfix Deserialized. (z. B. Deserialized.System.Data.DataTable ) sowie die Namen der Basis des Typs mit gleichem Präfix Typen (Vererbungshierarchie).

Außerdem die Rekursionstiefe für Objektgraphen von nicht -[pscustomobject] Instanzen ist auf 1 beschränkt Stufe - Beachten Sie, dass dies Instanzen von benutzerdefinierten PowerShell-Klassen beinhaltet , erstellt mit der class Schlüsselwort:Das heißt, wenn die Eigenschaftswerte eines Eingabeobjekts selbst keine Instanz bekannter Typen sind (letztere umfassen nur Einzelwerttypen, einschließlich primitiver .NET-Typen wie [int] , im Gegensatz zu Typen, die aus mehreren Eigenschaften bestehen), werden sie durch ihre .ToString() ersetzt Darstellungen (geben Sie z. B. System.IO.DirectoryInfo ein hat einen .Parent Eigenschaft, die eine andere System.IO.DirectoryInfo ist Instanz, was bedeutet, dass die .Parent Der Eigenschaftswert wird als .ToString() serialisiert Darstellung dieser Instanz, die ihre vollständige Pfadzeichenfolge ist); kurz gesagt:Nicht benutzerdefinierte (skalare) Objekte werden so serialisiert, dass Eigenschaftswerte, die selbst keine Instanzen bekannter Typen sind, durch ihre .ToString() ersetzt werden Vertretung ; siehe diese Antwort für ein konkretes Beispiel.
Im Gegensatz dazu explizit Verwendung der CLI-XML-Serialisierung über Export-Clixml ist standardmäßig auf eine Tiefe von 2 eingestellt (Sie können eine benutzerdefinierte Tiefe über -Depth angeben und Sie können die Tiefe auf ähnliche Weise steuern, wenn Sie den zugrunde liegenden System.Management.Automation.PSSerializer verwenden direkt eingeben ).

Je nach Originaltyp können Sie möglicherweise in der Lage sein, Instanzen des ursprünglichen Typs manuell zu rekonstruieren , aber das ist nicht garantiert. (Sie können den vollständigen Namen des ursprünglichen Typs erhalten, indem Sie .pstypenames[0] -replace '^Deserialized\.' aufrufen auf einem bestimmten benutzerdefinierten Objekt.)

Abhängig von Ihren Verarbeitungsanforderungen sind jedoch die Emulationen der Originalobjekte ausreichen.