【问题标题】:Powershell Job Step in SQL ErrorSQL 错误中的 Powershell 作业步骤
【发布时间】:2015-12-23 17:02:20
【问题描述】:

我是 PowerShell 的新手,并且还处于 SQL Server 的早期阶段,但我正在尝试为 SQL 代理作业编写一个 PowerShell 步骤,该作业查看包含 .sql 文件名称的 CSV 文件。

然后它应该查看另一个目录,如果 CSV 文件中的名称存在于该目录中,它应该打开 .sql 文件并执行其中的函数。

我收到一个错误:

无法将 'System.String 类型的对象转换为 System.Type 类型

任何帮助将不胜感激。

$excelFile = "C:/ExcelTest/Test.csv"
$functionDirectory = "some directory"

$excel_Array = (Get-Content $excelFile)[0].split(",")

foreach ($sqlName in $excel_Array) 
{
    if($sqlName::exists($functionDirectory + "/" + $sqlName) -ne $true) 
    {
        invoke-sqlcmd -inputfile $functionDirectory + "/" + $sqlName -serverinstance "serverinstance" -database "database"
    }
}

【问题讨论】:

  • $sqlName::exists() 应该做什么? $sqlName 是一个字符串,而字符串没有exists 成员
  • 你能贴出 CSV 文件的前几行吗?这会很有帮助。
  • @Eris DS_ESR_Day.sql, DS_ESR_PC_Month.sql, DS_GRgrtPEI_CP_Day.sql, DS_GRgrtPEI_Day.sql,我无法正确格式化,但在每个逗号之后都会换行。
  • @Eris 还有什么其他信息可以提供帮助吗?我已经调整了一段时间,得到了同样的错误。
  • @Eris 有什么想法吗?

标签: sql-server csv powershell sql-job


【解决方案1】:

如果正确理解问题,你需要使用Test-Path而不是::exists

$excelFile = "C:/ExcelTest/Test.csv"
$functionDirectory = "some directory"

Import-Csv $excelFile | 
    Foreach-Object {
        $filename = $functionDirectory + '\' + $_[0]
        if (Test-Path $filename) {
            invoke-sqlcmd -inputfile $filename -serverinstance "serverinstance" -database "database"
        }
    }

【讨论】:

  • 目标是让 powershell 查看 csv 的每一行(每一行都是一个 sql 文件名,如“Functionx.sql”),如果该 sql 文件存在于 $functionDirectory 中,它会打开$functionDirectory 中的 .sql 文件并运行内容。是不是更清楚了?
  • 好的,您的代码暗示所有文件名都在文件的第一行。我已更新代码以改用 Import-CSV
  • 收到错误“无法处理参数,因为参数“name”的值无效。更改“name”参数的值并再次运行操作”。我正在运行的完整代码。 $excelFile = "C:\ExcelTest\Test.csv" $functionDirectory = "C:\ActionMessages" Import-Csv $excelFile | Foreach-Object { $filename = $functionDirectory + '\' + $_[0] if (Test-Path $filename) { invoke-sqlcmd -inputfile $filename -serverinstance "" -database "" } }
【解决方案2】:

我会调整脚本中的一些内容以正确处理 CSV,然后利用内置 cmdlet 测试给定文件的路径。

[cmdletbinding()]
param()

Import-Module SQLPS -DisableNameChecking
$functionDirectory = "C:\temp\PowerShell_Testing2"
$excelFile = Import-Csv "C:\temp\PowerShell_Testing\SQLFileList.csv"

foreach ($e in $excelFile) {
    $fileonly = Split-Path $e.SQLFile -Leaf
    $fdFile = $functionDirectory + "\" + $fileonly
    if (Test-Path $fdFile) {
        Write-Host "Found File $fdFile"
        Invoke-Sqlcmd -ServerInstance "MANATARMS\SQL12" -InputFile $fdFile -Database master
    }
}

在我的设置中只有一个文件可以运行:

SELECT TOP 1 name FROM sys.databases

如果您的 CSV 包含一个 ServerName,然后是 SQLFile,您可以调整您的脚本以同时提取 ServerInstance 值,如下所示:

[cmdletbinding()]
param()

Import-Module SQLPS -DisableNameChecking
$functionDirectory = "C:\temp\PowerShell_Testing2"
$excelFile = Import-Csv "C:\temp\PowerShell_Testing\SQLFileList.csv"

foreach ($e in $excelFile) {
    $fileonly = Split-Path $e.SQLFile -Leaf
    $fdFile = $functionDirectory + "\" + $fileonly
    if (Test-Path $fdFile) {
        Write-Host "Found File $fdFile"
        Invoke-Sqlcmd -ServerInstance $e.ServerName -InputFile $fdFile -Database master
    }
}

【讨论】:

  • 您忘记了 Invoke-SqlCmd 上的数据库参数
  • @Shawn 从第一个示例中尝试了您的方法,因为 csv 不包含服务器名称,并导致调用 sql 行“缺少终止符”失败。
  • 处理您尝试执行的文件中的代码,您没有提供任何示例。
  • @ShawnMelton 文件中的 sql 不是问题,因为 sql 在您的 powershell 示例之外完美运行。即使从 ps 调用 sql 仍然可以。
  • 我会检查您从我的示例中复制/粘贴的代码,以确保 dash 在您的脚本版本中是正确的,并且没有被其他字符替换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多