通过从sql表中排除文件列表来读取sql文件,并使用PowerShell在单个Transaction中执行所有文件

时间:2019-01-26 06:41:04

标签: sql sql-server powershell transactions

我没有电源外壳方面的专家。我需要一个能够满足以下要求的脚本/方法。

我在一个文件夹中有文件列表,文件名称如下。

<input type="text" id="user-input" oninput="captureInput()">

<p id="user-output"></p>

<script>
function captureInput() {

var userInput = document.getElementById("user-input").value;
var elOutput = document.getElementById("user-output");
elOutput.innerHTML = "User Input: " + userInput;
var userOutput = elOutput.innerHTML;    
}
</script>

此外,我在sql server中有一个表,其中包含文件名称信息。

表名:带有文件名列的已执行文件。

001_File.sql
002_File.sql
003_File.sql
004_File.sql

我的要求是读取该文件夹中的可用文件,而不是该表中的文件

我只能读取文件:

002_File.sql
004_File.sql

现在,我需要在SQL Server上的同一事务下按顺序执行这两个文件。因为如果发生任何错误,我需要回滚所有事务。

到目前为止,我在下面写了一个电源壳。

001_File.sql
003_File.sql

请给我建议一些脚本。

挑战:

  1. 由于前导零,因此如何按顺序读取文件。上面的`Sort-Object $ _。Name'会排序吗?
  2. 如何在一次交易中执行所有文件列表。

谢谢

4 个答案:

答案 0 :(得分:0)

最后我做了这样的事情。

 $QueryResult = Invoke-Sqlcmd -ServerInstance 'MyServer' -Database 'MyDb' -Query "SELECT DISTINCT FNames from TableName"

 $FullScript = @()
 $FullScript += "BEGIN TRANSACTION;"


Get-ChildItem "E:\Testing\" -Filter *.sql | Sort-Object $_.Name|
Foreach-Object {

 if(!$QueryResult.FName.Contains($_.Name))
 {
    $FullScript += Get-Content $_.FullName
 }
}

$FullScript += "COMMIT TRANSACTION;"

sqlcmd -S localhost -d test -Q "$FullScript"

答案 1 :(得分:0)

尝试一下...

#get list of filenames from database...
$QueryResult = Invoke-Sqlcmd -ServerInstance 'MyServer' -Database 'MyDB' -Query "SELECT DISTINCT FNames from TableName" | Select-Object -ExpandProperty FileName

#get files from folder whose names are not in $queryresult...
$files = Get-ChildItem -Path E:\Testing -Filter *.sql | ? {(!($QueryResult.Contains($_.BaseName)))} | Sort-Object Name

#get the content of each $file and replace "GO" with empty string, etc...
$queries = @()

foreach ($file in $files) {

    $queries += (Get-Content $file.FullName).replace("GO","")

}

#join each query into a single T-SQL statement...
$singleTransaction = $queries -join ";"

#execute statement...
Invoke-Sqlcmd -ServerInstance 'SERVER' -Database 'DB' -Query $singleTransaction

要真正实现“单一交易” ...您可能必须要有一致的输入才能修改并放入一条语句中。我不确定您将需要怎么做。

答案 2 :(得分:0)

最后,我使用SMO对象编写了脚本来处理GO语句和事务。

$SqlFilePath = "D:\Roshan\Testing\SQL\"

$serverName = "MyServer"
$databaseName = "MyDB"

$QueryResult = Invoke-Sqlcmd -ServerInstance $serverName -Database $databaseName -Query "SELECT DISTINCT FName from dbo.TableName" -AS DataRows

$connection = new-object system.data.SqlClient.SQLConnection("Data Source=$serverName;Integrated Security=SSPI;Initial Catalog=$databaseName;Connection Timeout=600;Max Pool Size=10"); 
$Server = new-Object Microsoft.SqlServer.Management.Smo.Server(New-Object Microsoft.SqlServer.Management.Common.ServerConnection($connection))

$script_contents ="SET XACT_ABORT ON
                GO
                BEGIN TRANSACTION 
                GO"


Get-ChildItem $SqlFilePath -Filter *.sql| Sort-Object $_.Name|

ForEach-Object {

if(!$QueryResult.FName.Contains($_.Name))
{
    Write-Host $_.Name -ForegroundColor Magenta

    #[string]$script_contents = Get-Content $_.FullName
    $script_contents += [IO.File]::ReadAllText($_.FullName)

   #Write-Host $script_contents
   #$Server.ConnectionContext.ExecuteNonQuery($script_contents)
} 

} 

$script_contents+= " COMMIT TRANSACTION;"

$Server.ConnectionContext.ExecuteNonQuery($script_contents)

答案 3 :(得分:-1)

您可以在shell脚本中写一些东西

select filename from tablename; >> file.out
--->002_File.sql

grep -v 'file.out' * >> excludedfile.out