运行 来自 PS 的 sql 查询,并在 where 子句中循环条件

Run a sql query from PS, and loop in criteria in the where clause

我有通过解析文件名片段来创建索引文件的代码。

这个文件名: 25643245_AjaWar_Prav_2_FT_20200701.pdf

将在索引文件中创建这一行: 256432245|ST|W-高中成绩单|@@TEST-LOCATION643245_AjaWar_Prav_2_FT_20200701.pdf

问题是“256432245”的第一个解析不是我们数据库中的主键,所以我必须转换为主键,然后将主键存储到索引文件中以代替“256432245” '

我有部分构建索引文件的查询正常工作,但没有查询和 returns 转换后的 ID 的部分。如果我 运行 只有查询的一部分 returns 只有一个 ID,那也有效。我在让查询在“foreach”中工作时遇到问题。

我目前得到的结果是:

|ST|W-高中成绩单|@@TEST-LOCATION643245_AjaWar_Prav_2_FT_20200701.pdf

当我想得到:

8992004|ST|W-高中成绩单|@@TEST-LOCATION643245_AjaWar_Prav_2_FT_20200701.pdf

其中 '8992004' 是 SPRIDEN_ID 是 sql 查询的结果。

感谢您提供的任何帮助。

foreach ($Filename in Get-ChildItem $ImagePath)
{
$Arr = $Filename -split '_'
$reworkedfilename = $Arr[0] + '_' + $Arr[1] + '_' + $Arr[2] + '_' + $Arr[3] + '_' + $Arr[4] + '_' + $Arr[5]
##$reworkedarray2 = $Arr[0] -replace ".pdf", "";
Write-host $Arr[0] ##this works because I can see the non-primary ID being returned

#Find Each SPRIDEN_ID translated from CAID
add-type -AssemblyName System.Data.OracleClient
$username = "U"
$password = "P"
$data_source = "DS"
$connection_string = "User Id=$username;Password=$password;Data Source=$data_source"
$statement = "
Select Distinct SPRIDEN_ID
from SARACMT, SPRIDEN
where 
SPRIDEN_PIDM = SARACMT_PIDM
and SPRIDEN_CHANGE_IND is null
AND SARACMT_COMMENT_TEXT = '$Arr[0]'
"
##The "AND SARACMT_COMMENT_TEXT = '$Arr[0]'" doesn't work because nothing is being returned in the index file

try{
    $con = New-Object System.Data.OracleClient.OracleConnection($connection_string)

    $con.Open()
    $cmd = $con.CreateCommand()
    $cmd.CommandText = $statement
    $result = $cmd.ExecuteReader()
   
   # Do something with the results...
   $ArrConverted = while ($result.Read()) {
                    $result.GetString(0)
                    }
} catch {
    Write-Error (“Database Exception: {0}`n{1}” -f `
        $con.ConnectionString, $_.Exception.ToString())
} finally{
    if ($con.State -eq ‘Open’) { $con.close() }
}

$outputline =  $ArrConverted + '|' + $Arr[4] + '|' + $DocType + '|@@'+ $ImagePath + $reworkedfilename | out-file -filepath $IndexFilePath -Encoding "ascii" -append

#>
}


幸运的是我弄明白了。

我为 $Arr[0] 创建了一个变量

$Arr0 = $Arr[0]

然后把新变量放在sql语句的where子句的where子句中:

A​​ND SARACMT_COMMENT_TEXT = '$Arr0'

这 运行 在 foreach 期间解析出的每个项目的查询。

您的问题与您尝试将变量值注入 sql 查询字符串的方式有关:

$statement = "
Select Distinct SPRIDEN_ID
from SARACMT, SPRIDEN
where 
SPRIDEN_PIDM = SARACMT_PIDM
and SPRIDEN_CHANGE_IND is null
AND SARACMT_COMMENT_TEXT = '$Arr[0]'
"

如果您在此行之后添加 write-host $statement,您会看到它仅替换了 $Arr 部分,而 而不是 $Arr[0] 部分,所以您的查询包含类似:

Select Distinct SPRIDEN_ID
from SARACMT, SPRIDEN
where 
SPRIDEN_PIDM = SARACMT_PIDM
and SPRIDEN_CHANGE_IND is null
AND SARACMT_COMMENT_TEXT = '25643245 AjaWar Prav 2 FT 20200701[0]'

而不是:

Select Distinct SPRIDEN_ID
from SARACMT, SPRIDEN
where 
SPRIDEN_PIDM = SARACMT_PIDM
and SPRIDEN_CHANGE_IND is null
AND SARACMT_COMMENT_TEXT = '25643245’

要让它替换 $Arr[0] 的值,您可以用 $( ... ) 包围它以使用“命令替换”(参见 https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-string-substitutions?view=powershell-7#command-substitution),因此您的查询变为:

$statement = "
Select Distinct SPRIDEN_ID
from SARACMT, SPRIDEN
where 
SPRIDEN_PIDM = SARACMT_PIDM
and SPRIDEN_CHANGE_IND is null
AND SARACMT_COMMENT_TEXT = '$($Arr[0])’

话虽如此,使用参数化查询比构建动态 sql 字符串(参见 )要好得多,因为就您的代码而言,它容易受到 sql 注入攻击,如果你遇到故意恶作剧的文件名(例如 ‘ or 1='1_AjaWar_Prav_2_FT_20200701.pdf)。

有关 sql 注入攻击的更多信息,请参阅 https://blogs.oracle.com/sql/what-is-sql-injection-and-how-to-stop-it