使用 powershell 将数据插入到 ODBC 目标

Data inserting to ODBC destination with powershell

我需要将数据 table 加载到与 powershell 的 ODBC 驱动程序连接。 使用 OLEDB 和 SQL 服务器,我们可以使用批量复制并快速插入数据。

ODBC 有这种可能性吗?

我正在使用 powershell,因为它应该对这类操作有最好的支持, 但是我当前的代码没有使用任何一个 dll。

所以我的代码首先需要创建一个带有 两个 for 循环 的插入语句并迭代每一行并将其保存在内存中, 然后用1000行构造INSERT INTO,然后重复同样的事情。

我注定要这样吗?

    $Datatable = New-Object System.Data.DataTable
    $tabledump= $src_cmd.ExecuteReader()
    $Datatable.Load($tabledump)

    foreach ($item in $Datatable.Rows) {


        $f +=1


        for ($i = 0; $i -lt $item.ItemArray.Length; $i++) {
            $items = $item[$i] -replace "'" , "''"
            $val +="'"+ $items + "',"
        }

        $vals +=  $val




        if ($f % 1000 -eq 0 -or $f -eq $row_cnt) {

            $values = [system.String]::Join(" ", $vals)
            $values = $values.TrimEnd(",")


            $cols =  [system.String]::Join(",", $columns)


            $postgresCommand = "Insert Into $dst_schema.$dst_table ($cols) values $values"

            $dest_cmd_.CommandText = $postgresCommand



            $dest_cmd_.ExecuteNonQuery()

我承认代码不好,欢迎任何关于代码组合的建议。

您可以使用 Get-ODBCDSN 命令检索 ODBC 连接的值并将其用于查询

  $conn.ConnectionString= "DSN=$dsn;"
  $cmd = new-object System.Data.Odbc.OdbcCommand($query,$conn)
  $conn.open()
  $cmd.ExecuteNonQuery()
  $conn.close()

https://www.andersrodland.com/working-with-odbc-connections-in-powershell/

但 ODBC 提供程序不执行批量复制

https://docs.microsoft.com/en-us/sql/relational-databases/native-client-odbc-bulk-copy-operations/performing-bulk-copy-operations-odbc?view=sql-server-ver15

我知道这个 post 不是新的,但我一直在四处寻找解决方案,但也一无所获,但是这个 post 给了我一些见解。
第一:没有'Bad Code'这样的东西。如果它有效还不错,即使它无效,但它帮助了一些东西..

好吧,我做的不是最好的解决方案,但我正在尝试在 PostgreSQL 上导入 Active Directory 数据,所以... 我注意到您也在尝试使用 pgsql,因此您可以使用 COPY 语句。 https://www.postgresql.org/docs/9.2/sql-copy.html
https://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/

在我的例子中,我将它与 csv 文件一起使用:
*假设你已经安装了 pgsql ODBC 驱动

$DBConn = New-Object System.Data.Odbc.OdbcConnection
$DBConnectionString = "Driver={PostgreSQL UNICODE(x64)};Server=$ServerInstance;Port=$Port;Database=$Database;Uid=$Username;Pwd=$(ConvertFrom-SecureString -SecureString $Password);"
$DBConn.ConnectionString = $DBConnectionString
try 
{
    $ADFObject = @()
    $ADComputers = Get-ADComputer -Filter * -SearchBase "OU=Some,OU=OrgU,OU=On,DC=Domain,DC=com" -Properties Description,DistinguishedName,Enabled,LastLogonTimestamp,modifyTimestamp,Name,ObjectGUID | Select-Object Description,DistinguishedName,Enabled,LastLogonTimestamp,modifyTimestamp,Name,ObjectGUID
    foreach ($ADComputer in $ADComputers) {
        switch ($ADComputer.Enabled) {
            $true {
                $ADEnabled = 1
            }
            $false {
                $ADEnabled = 0
            }
        }
        $ADFObject += [PSCustomObject] @{
            ADName = $ADComputer.Name
            ADInsert_Time = Get-Date
            ADEnabled = $ADEnabled
            ADDistinguishedName = $ADComputer.DistinguishedName
            ADObjectGUID = $ADComputer.ObjectGUID
            ADLastLogonTimestamp = [datetime]::FromFileTime($ADComputer.LastLogonTimestamp)
            ADModifyTimestamp = $ADComputer.modifyTimestamp
            ADDescription = $ADComputer.Description
        }
    }
    $ADFObject | Export-Csv $Env:TEMP\TempPsAd.csv -Delimiter ',' -NoTypeInformation
    docker cp $Env:TEMP\TempPsAd.csv postgres_docker:/media/TempPsAd.csv
    $DBConn.Open()
    $DBCmd = $DBConn.CreateCommand()
    $DBCmd.CommandText = @"
        COPY AD_Devices (ADName,ADInsert_Time,ADEnabled,ADDistinguishedName,ADObjectGUID,ADLastLogonTimestamp,ADModifyTimestamp,ADDescription)
        FROM '/media/TempPsAd.csv'
        DELIMITER ','
        CSV HEADER
"@
    $DBCmd.ExecuteReader()
    $DBConn.Close()
    docker exec postgres_docker rm -rf /media/TempPsAd.csv
    Remove-Item $Env:TEMP\TempPsAd.csv -Force
} 
catch 
{ 
    Write-Error "$($_.Exception.Message)"
    continue 
}

希望对您有所帮助!
干杯!