Artikel iki murni praktis lan khusus kanggo crita sedihku
Siap-siap kanggo PROD Tutul Zero kanggo RDS (MS SQL), bab kang kabeh kuping kita padha buzzing, Aku nggawe presentation (POC - Proof Of Concept) automation: pesawat saka skrip powershell. Sawise presentation, nalika badai, keplok ingkang dipun danguaken mati mudhun, ngowahi menyang incessant keplok, padha marang kula - kabeh iki apik, nanging mung kanggo alasan ideologi, kabeh budak Jenkins kita makarya ing Linux!
Apa iki bisa? Njupuk DBA anget, lampu saka ing Windows lan kelet ing panas banget saka powershell ing Linux? Apa ora iki kejem?
Aku kudu nyemplungaken dhewe ing kombinasi aneh iki teknologi. Mesthi, kabeh 30+ skrip saya mandheg. Kanggo kaget, aku bisa ndandani kabeh ing sawijining dina kerja. Aku nulis ing nguber panas. Dadi, pitfalls apa sing bisa sampeyan temoni nalika nransfer skrip powershell saka Windows menyang Linux?
Yen ora ana EXIT ing pungkasan, sqlcmd bakal nerusake ngenteni input, lan yen sadurunge MUTU РР¡¡ ± ± ± GO, banjur printah pungkasan ora bakal bisa. File output ngemot kabeh output, pilih, pesen, print, etc.
Invoke-SqlCmd ngasilake asil minangka DataSet, DataTables utawa DataRows. Mulane, yen sampeyan ngolah asil saka pilihan prasaja, sampeyan bisa nggunakake sqlcmd, Duwe parsed sawijining output, iku meh mokal kanggo niru soko Komplek: kanggo iki ana Invoke-SqlCmd. Nanging tim iki uga duwe lelucon dhewe:
Yen sampeyan nransfer file menyang dheweke liwat -InputFile, banjur MUTU ora perlu, malih, iku mrodhuksi kesalahan sintaksis
-OutputFile ora, printah ngasilake asil minangka obyek
Ana rong sintaksis kanggo nemtokake server: -ServerInstance -Jeneng pangguna -Sandi -Database lan liwat -KoneksiString. Cukup aneh, ing kasus sing sepisanan ora bisa nemtokake port liyane saka 1433.
output teks, ketik PRINT, sing mung "dicekel" sqlcmdkanggo Invoke-SqlCmdiku masalah
Dadi ing kene. Ing *nix substitusi variabel ora bisa... Parameter -v digatekake. U Invoke-SqlCmd digatekake -Variabel. Sanajan parameter sing nemtokake variabel dhewe ora digatekake, substitusi dhewe bisa digunakake-sampeyan bisa nggunakake variabel apa wae saka Shell. Nanging, aku gelo karo variabel kasebut lan mutusake ora gumantung ing kabeh, lan tumindak kasar lan primitif, amarga skrip SQL cendhak:
Iki, kaya sing sampeyan ngerteni, minangka tes saka versi Unix.
Ngunggah file
Ing versi Windows, operasi apa wae sing diiringi audit: kita mlayu sqlcmd, nampa sawetara jenis penyalahgunaan ing file output, ditempelake file iki menyang piring audit. Untunge, server SQL makarya ing server sing padha karo Jenkins, wis rampung kaya mangkene:
CREATE procedure AuditUpload
@id int, @filename varchar(256)
as
set nocount on
declare @sql varchar(max)
CREATE TABLE #multi (filer NVARCHAR(MAX))
set @sql='BULK INSERT #multi FROM '''+@filename
+''' WITH (ROWTERMINATOR = '' '',CODEPAGE = ''ACP'')'
exec (@sql)
select @sql=filer from #multi
update JenkinsAudit set multiliner=@sql where ID=@id
return
Mangkono, kita ngulu file BCP tanggung lan shove menyang nvarchar(max) lapangan ing meja audit. Mesthine, kabeh sistem iki ambruk, amarga tinimbang server SQL aku entuk RDS, lan BULK INSERT ora bisa digunakake liwat UNC amarga nyoba njupuk kunci eksklusif ing file, lan kanthi RDS iki umume ditakoni. wiwitan banget. Dadi aku mutusake kanggo ngganti desain sistem, nyimpen baris audit kanthi baris:
CREATE TABLE AuditOut (
ID int NULL,
TextLine nvarchar(max) NULL,
n int IDENTITY(1,1) PRIMARY KEY
)
Lan nulis ing tabel iki kaya mangkene:
function WriteAudit([string]$Filename, [string]$ConnStr,
[string]$Tabname, [string]$Jobname)
{
# get $lastid of the last execution -- ΠΏΡΠΎΡΠΊΠΈΠΏΠ°Π½ΠΎ Π΄Π»Ρ ΡΡΠ°ΡΡΠΈ
#create grid and populate it with data from file
$audit = Get-Content $Filename
$DT = new-object Data.DataTable
$COL1 = new-object Data.DataColumn;
$COL1.ColumnName = "ID";
$COL1.DataType = [System.Type]::GetType("System.Int32")
$COL2 = new-object Data.DataColumn;
$COL2.ColumnName = "TextLine";
$COL2.DataType = [System.Type]::GetType("System.String")
$DT.Columns.Add($COL1)
$DT.Columns.Add($COL2)
foreach ($line in $audit)
{
$DR = $dt.NewRow()
$DR.Item("ID") = $lastid
$DR.Item("TextLine") = $line
$DT.Rows.Add($DR)
}
# write it to table
$conn=new-object System.Data.SqlClient.SQLConnection
$conn.ConnectionString = $ConnStr
$conn.Open()
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $ConnStr
$bulkCopy.DestinationTableName = $Tabname
$bulkCopy.BatchSize = 50000
$bulkCopy.BulkCopyTimeout = 0
$bulkCopy.WriteToServer($DT)
$conn.Close()
}
Kanggo milih isi, sampeyan kudu milih miturut ID, milih ing urutan n (identitas).
Ing artikel sabanjure aku bakal luwih rinci babagan carane kabeh iki sesambungan karo Jenkins.