Ag obair le MS SQL ó Powershell ar Linux

Tá an t-alt seo praiticiúil amháin agus tá sé tiomanta do mo scéal brónach

Ag fáil réidh le haghaidh Zero Touch PROD le haghaidh RDS (MS SQL), a raibh ár gcluasa go léir ag magadh fúthu, rinne mé cur i láthair (POC - Proof Of Concept) uathoibrithe: sraith scripteanna powershell. Tar éis an cur i láthair, nuair a fuair an bualadh bos stoirmiúil, fada síos, ag iompú isteach i bualadh bos gan staonadh, dúirt siad liom - tá sé seo go léir go maith, ach amháin ar chúiseanna idé-eolaíocha, oibríonn ár sclábhaithe Jenkins go léir ar Linux!

An bhfuil sé seo indéanta? Tóg a leithéid de lampa te, DBA ó faoi Windows agus é a ghreamú sa teas an-chumhachtach faoi Linux? Nach bhfuil sé seo cruálach?

Ag obair le MS SQL ó Powershell ar Linux
Bhí orm mé féin a thumadh sa chomhcheangal aisteach seo de theicneolaíochtaí. Ar ndóigh, stop mo 30+ scripteanna go léir ag obair. Chun mo choinne, d'éirigh liom gach rud a shocrú in aon lá oibre amháin. Táim ag scríobh ar thóir te. Mar sin, cad iad na contúirtí a d'fhéadfadh teacht ort agus tú ag aistriú scripteanna powershell ó Windows go Linux?

sqlcmd vs Invoke-SqlCmd

Lig dom i gcuimhne duit an difríocht is mó eatarthu. Dea-áisiúlacht d'aois sqlcmd Oibríonn sé freisin faoi Linux, le feidhmiúlacht beagnach mar an gcéanna. Gabhaimid an cheist chun -Q a fhorghníomhú, an comhad ionchuir mar -i, agus an t-aschur mar -o. Ach, ar ndóigh, déantar cás-íogair do na hainmneacha comhaid. Má úsáideann tú -i, scríobh ag an deireadh sa chomhad:

GO
EXIT

Mura bhfuil EXIT ag an deireadh, ansin rachaidh sqlcmd ar aghaidh chun fanacht le hionchur, agus más rud é roimhe seo Scoir ní bheidh GO, ansin ní oibreoidh an t-ordú deireanach. Cuimsíonn an comhad aschur go léir an t-aschur, roghnaíonn, teachtaireachtaí, a phriontáil, etc.

Táirgeann Invoke-SqlCmd an toradh mar Thacar Sonraí, DataTables nó DataRows. Dá bhrí sin, má phróiseálann tú toradh roghnú simplí, is féidir leat é a úsáid sqlcmd, tar éis a aschur a pharsáil, tá sé beagnach dodhéanta rud casta a dhíorthú: chuige seo tá agairt-SqlCmd. Ach tá a scéalta grinn féin ag an bhfoireann seo freisin:

  • Má aistríonn tú comhad chuici via -InputFileansin Scoir ní gá, ina theannta sin, cruthaíonn sé earráid chomhréire
  • -AschurFile ní hea, tugann an t-ordú an toradh ar ais duit mar rud
  • Tá dhá chomhréir ann chun freastalaí a shonrú: -ServerInstance -Ainm Úsáideora -Pasfhocal -Bunachar Sonraí agus tríd -ConnectionString. Is aisteach go leor, sa chéad chás nach féidir calafort seachas 1433 a shonrú.
  • aschur téacs, clóscríobh PRINT, atá “gafa” go simplí sqlcmddo agairt-SqlCmd Is fadhb
  • Agus is tábhachtaí: Is dócha nach bhfuil an cmdlet seo ag do Linux!

Agus is é seo an fhadhb is mó. Ach amháin i mí an Mhárta an cmdlet seo ar fáil le haghaidh ardáin neamh-Windows, agus ar deireadh is féidir linn dul ar aghaidh!

Ionadú inathraithe

Tá ionadú athraitheach ag sqlcmd ag baint úsáide as -v, mar shampla mar seo:

# $conn содержит начало команды sqlcmd
$cmd = $conn + " -i D:appsSlaveJobsKillSpid.sql -o killspid.res 
  -v spid =`"" + $spid + "`" -v age =`"" + $age + "`""
Invoke-Expression $cmd

Sa script SQL úsáidimid ionaid:

set @spid=$(spid)
set @age=$(age)

Mar sin anseo tá sé. I *nix ní oibríonn ionaid inathraithe... Paraiméadar -v neamhaird. U agairt-SqlCmd neamhaird -Athróga. Cé go ndéantar neamhaird den pharaiméadar a shonraíonn na hathróga féin, oibríonn na hionadaithe iad féin - is féidir leat aon athróg a úsáid ó Shell. Mar sin féin, chuir na hathróga olc orm agus chinn mé gan brath orthu ar chor ar bith, agus d'fheidhmigh mé go rudely agus go primitive, ós rud é go bhfuil na scripteanna SQL gearr:

# prepend the parameters  
"declare @age int, @spid int" | Add-Content "q.sql"
"set @spid=" + $spid | Add-Content "q.sql"
"set @age=" + $age | Add-Content "q.sql"

foreach ($line in Get-Content "Sqlserver/Automation/KillSpid.sql") { 
  $line | Add-Content "q.sql" 
  }
$cmd = "/opt/mssql-tools/bin/" + $conn + " -i q.sql -o res.log"

Is tástáil é seo, mar a thuigeann tú, ón leagan Unix cheana féin.

Comhaid a uaslódáil

Sa leagan Windows, bhí iniúchadh ag gabháil le haon oibríocht: ritheamar sqlcmd, fuaireamar mí-úsáid de chineál éigin sa chomhad aschuir, ceangailte an comhad seo leis an pláta iniúchta. Go fortunately, d'oibrigh freastalaí SQL ar an bhfreastalaí céanna le Jenkins, rinneadh rud éigin mar seo:

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

Mar sin, déanaimid an comhad BCP a shlogadh go hiomlán agus a chur isteach sa réimse nvarchar(max) den tábla iniúchta. Ar ndóigh, thit an córas ar fad as a chéile, mar in ionad freastalaí SQL fuair mé RDS, agus ní oibríonn BULK INSERT ar chor ar bith trí UNC mar gheall ar iarracht glas eisiach a ghlacadh ar chomhad, agus le RDS déantar é seo de ghnáth ó an tús. Mar sin chinn mé dearadh an chórais a athrú, ag stóráil an iniúchta líne ar líne:

CREATE TABLE AuditOut (
  ID int NULL,
  TextLine nvarchar(max) NULL,
  n int IDENTITY(1,1) PRIMARY KEY
  )

Agus scríobh sa tábla seo mar seo:

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() 
  }  

Chun ábhar a roghnú, ní mór duit a roghnú de réir aitheantais, ag roghnú in ord n ​​(aitheantas).

Sa chéad alt eile rachaidh mé isteach go mion faoin gcaoi a n-idirghníomhaíonn sé seo go léir le Jenkins.

Foinse: will.com

Add a comment