لینکس پر پاورشیل سے MS SQL کے ساتھ کام کرنا

یہ مضمون خالصتاً عملی ہے اور میری دکھ بھری کہانی کے لیے وقف ہے۔

کے لیے تیار ہو رہا ہے۔ زیرو ٹچ PROD RDS (MS SQL) کے لیے، جس کے بارے میں ہمارے تمام کان گونج رہے تھے، میں نے آٹومیشن کی ایک پریزنٹیشن (POC - Proof Of Concept) کی: پاور شیل اسکرپٹس کا ایک سیٹ۔ پریزنٹیشن کے بعد، جب طوفانی، طویل تالیاں دم توڑ گئیں، لگاتار تالیوں میں بدل گئیں، تو انہوں نے مجھ سے کہا - یہ سب اچھا ہے، لیکن صرف نظریاتی وجوہات کی بنا پر، ہمارے تمام جینکنز غلام لینکس پر کام کرتے ہیں!

کیا یہ ممکن ہے؟ ونڈوز کے نیچے سے اتنا گرم، لیمپ ڈی بی اے لیں اور اسے لینکس کے نیچے پاور شیل کی بہت گرمی میں چپکائیں؟ کیا یہ ظلم نہیں؟

لینکس پر پاورشیل سے MS SQL کے ساتھ کام کرنا
مجھے ٹیکنالوجی کے اس عجیب امتزاج میں خود کو غرق کرنا پڑا۔ یقیناً، میری تمام 30+ اسکرپٹس نے کام کرنا چھوڑ دیا۔ میری حیرت کی بات یہ ہے کہ میں ایک کام کے دن میں سب کچھ ٹھیک کرنے میں کامیاب ہوگیا۔ میں گرم تعاقب میں لکھ رہا ہوں۔ تو، پاورشیل اسکرپٹس کو ونڈوز سے لینکس میں منتقل کرتے وقت آپ کو کن نقصانات کا سامنا کرنا پڑ سکتا ہے؟

sqlcmd بمقابلہ Invoke-SqlCmd

میں آپ کو ان کے درمیان بنیادی فرق کی یاد دلاتا ہوں۔ اچھی پرانی افادیت sqlcmd یہ تقریباً ایک جیسی فعالیت کے ساتھ، لینکس کے تحت بھی کام کرتا ہے۔ ہم -Q پر عمل کرنے کے لیے استفسار پاس کرتے ہیں، ان پٹ فائل کو -i، اور آؤٹ پٹ کو -o۔ لیکن فائل کے نام، یقیناً، کیس کے لحاظ سے حساس بنائے گئے ہیں۔ اگر آپ -i استعمال کرتے ہیں، تو فائل میں آخر میں لکھیں:

GO
EXIT

اگر آخر میں کوئی EXIT نہیں ہے، تو sqlcmd ان پٹ کا انتظار کرنے کے لیے آگے بڑھے گا، اور اگر پہلے باہر نکلیں نہیں کریں گے GO، پھر آخری کمانڈ کام نہیں کرے گا۔ آؤٹ پٹ فائل میں تمام آؤٹ پٹ، سلیکٹس، میسجز، پرنٹ وغیرہ شامل ہیں۔

Invoke-SqlCmd ڈیٹا سیٹ، ڈیٹا ٹیبلز یا ڈیٹا روز کے طور پر نتیجہ تیار کرتا ہے۔ لہذا، اگر آپ ایک سادہ انتخاب کے نتیجے پر کارروائی کرتے ہیں، تو آپ استعمال کر سکتے ہیں۔ sqlcmdاس کے آؤٹ پٹ کو پارس کرنے کے بعد، کوئی پیچیدہ چیز اخذ کرنا تقریباً ناممکن ہے: اس کے لیے Invoke-SqlCmd. لیکن اس ٹیم کے اپنے لطیفے بھی ہیں:

  • اگر آپ اس کے ذریعے فائل منتقل کرتے ہیں۔ -ان پٹ فائلپھر باہر نکلیں ضرورت نہیں ہے، مزید یہ کہ یہ نحوی غلطی پیدا کرتا ہے۔
  • -آؤٹ پٹ فائل نہیں، کمانڈ آپ کو ایک شے کے طور پر نتیجہ لوٹاتا ہے۔
  • سرور کی وضاحت کے لیے دو نحو ہیں: -ServerInstance -Username -Password -Database اور کے ذریعے - کنکشن سٹرنگ. عجیب بات یہ ہے کہ پہلی صورت میں 1433 کے علاوہ کسی بندرگاہ کی وضاحت کرنا ممکن نہیں ہے۔
  • ٹیکسٹ آؤٹ پٹ، ٹائپ کریں PRINT، جو کہ صرف "پکڑا گیا" ہے sqlcmdکے لئے Invoke-SqlCmd ایک مسئلہ ہے
  • اور سب سے اہم: غالباً آپ کے لینکس میں یہ cmdlet نہیں ہے!

اور یہ بنیادی مسئلہ ہے۔ صرف مارچ میں اس cmdlet غیر ونڈوز پلیٹ فارمز کے لیے دستیاب ہو گیا۔، اور آخر کار ہم آگے بڑھ سکتے ہیں!

متغیر متبادل

sqlcmd میں -v کا استعمال کرتے ہوئے متغیر متبادل ہے، مثال کے طور پر اس طرح:

# $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 نظر انداز کیا یو Invoke-SqlCmd نظر انداز کیا - متغیرات. اگرچہ وہ پیرامیٹر جو خود متغیرات کی وضاحت کرتا ہے اسے نظر انداز کر دیا جاتا ہے، لیکن متبادل خود کام کرتے ہیں — آپ شیل سے کوئی بھی متغیر استعمال کر سکتے ہیں۔ تاہم، میں متغیرات سے ناراض ہوا اور میں نے ان پر بالکل بھی انحصار نہ کرنے کا فیصلہ کیا، اور میں نے بدتمیزی اور ابتدائی طور پر کام کیا، کیونکہ ایس کیو ایل اسکرپٹ مختصر ہیں:

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

یہ، جیسا کہ آپ سمجھتے ہیں، یونکس ورژن کا پہلے سے ہی ایک ٹیسٹ ہے۔

فائلیں اپ لوڈ ہو رہی ہیں۔

ونڈوز ورژن میں، کسی بھی آپریشن کے ساتھ آڈٹ ہوتا تھا: ہم نے sqlcmd چلایا، آؤٹ پٹ فائل میں کسی قسم کا غلط استعمال کیا، اس فائل کو آڈٹ پلیٹ سے منسلک کیا۔ خوش قسمتی سے، SQL سرور نے جینکنز کے طور پر ایک ہی سرور پر کام کیا، یہ کچھ اس طرح کیا گیا تھا:

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

اس طرح، ہم BCP فائل کو مکمل طور پر نگلتے ہیں اور اسے آڈٹ ٹیبل کے nvarchar(max) فیلڈ میں ڈال دیتے ہیں۔ یقیناً، یہ پورا سسٹم الگ ہو گیا، کیونکہ مجھے ایس کیو ایل سرور کے بجائے RDS ملا، اور BULK INSERT کسی فائل پر خصوصی لاک لینے کی کوشش کی وجہ سے UNC کے ذریعے بالکل کام نہیں کرتا، اور RDS کے ساتھ یہ عام طور پر برباد ہو جاتا ہے۔ بہت شروع. لہذا میں نے نظام کے ڈیزائن کو تبدیل کرنے کا فیصلہ کیا، آڈٹ لائن کو لائن کے ذریعے ذخیرہ کیا:

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

مواد کو منتخب کرنے کے لیے، آپ کو n (شناخت) کی ترتیب میں منتخب کرتے ہوئے، ID کے لحاظ سے منتخب کرنے کی ضرورت ہے۔

اگلے مضمون میں میں مزید تفصیل میں جاؤں گا کہ یہ سب جینکنز کے ساتھ کیسے تعامل کرتا ہے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں