Dieser Artikel ist rein praktisch und widmet sich meiner traurigen Geschichte.
Als
ich mich auf
Zero Touch PROD für RDS (MS SQL)
vorbereitete , über das alle unsere Ohren schwirrten, hielt ich eine Präsentation (POC - Proof Of Concept) der Automatisierung: eine Reihe von Powershell-Skripten. Nach der Präsentation, als der laute, anhaltende Applaus nachließ und sich in unaufhörliche Ovationen verwandelte, wurde mir gesagt, dass dies alles gut ist, aber nur aus ideologischen Gründen haben wir alle Jenkins-Sklaven unter Linux!
Ist das möglich Um einen so warmen Röhren-DBA unter Windows herauszunehmen und ihn unter Linux in die Hitze der PowerShell zu bringen? Ist das nicht grausam?
Ich musste in diese seltsame Kombination von Technologie eintauchen. Natürlich funktionierten alle meine über 30 Skripte nicht mehr. Zu meiner Überraschung gelang es mir an einem Arbeitstag, alles zu reparieren. Ich schreibe in Verfolgung. Auf welche Fallstricke können Sie beim Portieren von Powershell-Skripten von Windows nach Linux stoßen?
sqlcmd vs Invoke-SqlCmd
Ich möchte Sie an den Hauptunterschied zwischen ihnen erinnern. Das gute alte Dienstprogramm
sqlcmd funktioniert auch unter Linux mit nahezu identischer Funktionalität. Um die Abfrage auszuführen, übergeben wir -Q, die Eingabedatei als -i und die Ausgabe -o. Hier sind natürlich nur die Dateinamen, bei denen zwischen Groß- und Kleinschreibung unterschieden wird. Wenn Sie -i verwenden, schreiben Sie am Ende in die Datei:
GO EXIT
Wenn am Ende kein EXIT vorhanden ist, wartet sqlcmd auf die Eingabe, und wenn vor dem
EXIT kein
GO vorhanden ist, funktioniert der letzte Befehl nicht. Alle Ausgaben, Auswahlen, Nachrichten, Drucke usw. gelangen in die Ausgabedatei.
Invoke-SqlCmd gibt das Ergebnis als DataSet, DataTables oder DataRows zurück. Wenn Sie also das Ergebnis einer einfachen Auswahl verarbeiten, können Sie auch
sqlcmd verwenden, um die Ausgabe
zu analysieren. Die Ausgabe von etwas Kompliziertem ist daher fast unmöglich:
Dafür gibt es
Invoke-SqlCmd . Aber dieses Team hat seine eigenen Witze:
- Wenn Sie die Datei über -InputFile an sie übergeben , wird EXIT nicht benötigt. Außerdem wird ein Syntaxfehler ausgegeben
- -OutputFile nicht, der Befehl gibt Ihnen das Ergebnis als Objekt zurück
- Es gibt zwei Syntaxen zum Angeben eines Servers: -ServerInstance -Username -Password -Database und über -ConnectionString . Seltsamerweise können Sie im ersten Fall keinen anderen Port als 1433 angeben.
- Die Textausgabe vom Typ PRINT, die von sqlcmd auf elementare Weise „abgefangen“ wird, ist ein Problem für Invoke-SqlCmd
- Und vor allem: Wahrscheinlich befindet sich dieses Cmdlet nicht in Ihrem Linux!
Und das ist das Hauptproblem. Erst im März wurde dieses Cmdlet
für Nicht-Windows-Plattformen verfügbar , und endlich können wir weitermachen!
Variable Substitution
Sqlcmd hat eine variable Substitution durch -v, wie folgt:
Im SQL-Skript verwenden wir Substitutionen:
set @spid=$(spid) set @age=$(age)
Also. In * nix
funktionieren Variablensubstitutionen nicht . Die
Option -v wird ignoriert.
Invoke-SqlCmd ignoriert
-Variables . Obwohl der Parameter, der die Variablen selbst festlegt, ignoriert wird, funktionieren die Ersetzungen selbst - Sie können beliebige Variablen aus Shell verwenden. Ich war jedoch von den Variablen beleidigt und entschied mich, überhaupt nicht von ihnen abhängig zu sein, und ich handelte grob und primitiv, da die Skripte für SQL kurz sind:
Dies ist, wie Sie verstehen, ein Test aus der Unix-Version.
Dateien hochladen
In der Windows-Version wurde jede Operation, die ich hatte, von einer Prüfung begleitet: Sie führten sqlcmd durch, erhielten einen Missbrauch in der Ausgabedatei und hängten diese Datei an die Prüfplatte an. Glücklicherweise arbeitete SQL Server auf demselben Server wie Jenkins. Es wurde ungefähr so vorgegangen:
CREATE procedure AuditUpload @id int, @filename varchar(256) as set nocount on declare @sql varchar(max) CREATE TABLE
Daher verschlucken wir die gesamte BCP-Datei und verschieben die Prüftabelle in das Feld nvarchar (max). Natürlich ist dieses ganze System zusammengebrochen, weil ich anstelle von SQL Server RDS habe und BULK INSERT auf \\ UNC im Allgemeinen nicht funktioniert, weil versucht wird, eine Datei exklusiv zu sperren, und mit RDS ist dies im Allgemeinen von Anfang an zum Scheitern verurteilt. Deshalb habe ich beschlossen, das Design des Systems zu ändern und das Audit zeilenweise zu speichern:
CREATE TABLE AuditOut ( ID int NULL, TextLine nvarchar(max) NULL, n int IDENTITY(1,1) PRIMARY KEY )
Und schreiben Sie wie folgt in diese Tabelle:
function WriteAudit([string]$Filename, [string]$ConnStr, [string]$Tabname, [string]$Jobname) {
Um Inhalte auszuwählen, wählen Sie nach ID und anschließend n (Identität).
Im nächsten Artikel werde ich näher darauf eingehen, wie dies alles mit Jenkins interagiert.