Рад са МС СКЛ-ом из Поверсхелл-а на Линук-у

Овај чланак је чисто практичан и посвећен је мојој тужној причи

Спремам се за Зеро Тоуцх ПРОД за РДС (МС СКЛ), о коме су нам све уши брујале, направио сам презентацију (ПОЦ - Прооф Оф Цонцепт) аутоматизације: скуп поверсхелл скрипти. Након излагања, када је буран, пролонгиран аплауз утихнуо, прешао у непрестан аплауз, рекли су ми – све је то добро, али само из идеолошких разлога, сви наши Џенкинсови робови раде на Линуксу!

Да ли је то могуће? Узмите тако топлу, лампу ДБА испод Виндовс-а и ставите је у саму врућину поверсхелл-а под Линуком? Није ли ово окрутно?

Рад са МС СКЛ-ом из Поверсхелл-а на Линук-у
Морао сам да се уроним у ову чудну комбинацију технологија. Наравно, свих мојих 30+ скрипти су престале да раде. На моје изненађење, успео сам све да поправим за један радни дан. Пишем у журби. Дакле, на које замке можете наићи када преносите поверсхелл скрипте са Виндовс-а на Линук?

склцмд против Инвоке-СклЦмд

Дозволите ми да вас подсетим на главну разлику између њих. Добар стари услужни програм склцмд Такође ради под Линуком, са скоро идентичном функционалношћу. Проследимо упит за извршење -К, улазну датотеку као -и, а излазну као -о. Али имена датотека, наравно, разликују се велика и мала слова. Ако користите -и, онда у датотеци напишите на крају:

GO
EXIT

Ако на крају нема ЕКСИТ-а, онда ће склцмд наставити да чека на унос, а ако пре ЕКСИТ неће GO, онда последња команда неће радити. Излазна датотека садржи сав излаз, одабире, поруке, штампање итд.

Инвоке-СклЦмд производи резултат као ДатаСет, ДатаТаблес или ДатаРовс. Стога, ако обрадите резултат једноставног одабира, можете користити склцмд, након рашчлањивања његовог излаза, готово је немогуће извести нешто сложено: за ово постоји Инвоке-СклЦмд. Али и овај тим има своје шале:

  • Ако јој пренесете датотеку преко -Улазни документ, Онда ЕКСИТ није потребан, штавише, производи синтаксичку грешку
  • -Излазни фајл не, команда вам враћа резултат као објекат
  • Постоје две синтаксе за одређивање сервера: -СерверИнстанце -Корисничко име -Лозинка -База података i kroz -ЦоннецтионСтринг. Чудно, у првом случају није могуће навести порт који није 1433.
  • излаз текста, откуцајте ПРИНТ, који је једноставно „ухваћен“ склцмдза Инвоке-СклЦмд је проблем
  • И што је најважније: Највероватније ваш Линук нема овај цмдлет!

И ово је главни проблем. Само у марту овај цмдлет постао доступан за не-Виндовс платформе, и коначно можемо да идемо напред!

Замена променљиве

склцмд има замену променљиве помоћу -в, на пример овако:

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

У СКЛ скрипти користимо замене:

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

Дакле, ево га. У *ник замене променљивих не раде. Параметар -v игнорисано. У Инвоке-СклЦмд игнорисано -Променљиве. Иако се параметар који специфицира саме променљиве игнорише, саме замене функционишу—можете да користите било коју променљиву из Схелл-а. Међутим, био сам увређен због променљивих и одлучио сам да уопште не зависим од њих, и поступио сам грубо и примитивно, пошто су СКЛ скрипте кратке:

# 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"

Ово је, као што разумете, тест већ из Уник верзије.

Otpremanje datoteka

У верзији за Виндовс, свака операција је била праћена ревизијом: покренули смо склцмд, примили неку врсту злоупотребе у излазној датотеци, приложили ову датотеку на плочу за ревизију. На срећу, СКЛ сервер је радио на истом серверу као и Џенкинс, урађено је отприлике овако:

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

Дакле, у потпуности прогутамо БЦП датотеку и угурамо је у поље нварцхар(мак) табеле ревизије. Наравно, цео овај систем се распао, јер сам уместо СКЛ сервера добио РДС, а БУЛК ИНСЕРТ уопште не ради преко УНЦ-а због покушаја преузимања ексклузивног закључавања фајла, а са РДС-ом је ово генерално осуђено на пропаст. самом почетку. Зато сам одлучио да променим дизајн система тако што сам чувао ревизију ред по ред:

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

И запишите у ову табелу овако:

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

Да бисте изабрали садржај, потребно је да изаберете по ИД-у, бирајући редоследом н (идентитет).

У следећем чланку ћу детаљније о томе како све ово утиче на Џенкинса.

Извор: ввв.хабр.цом

Додај коментар