簡體   English   中英

缺少將數組變量從csv文件傳遞到invoke-sqlcmd插入語句的值?

[英]Missing values passing array variables from csv file to invoke-sqlcmd insert statement?

我正在學習PowerShell,我已經構建了一個腳本,試圖將.CSV文件導入到我的SQL Server數據庫中,發現以下查詢只是在追加表。

$database = 'DATABASE'
$server = 'SERVER'
$table = 'TABLE'
Import-CSV \\TESTPATH\licenses_v2.csv  | 
ForEach-Object { 
Invoke-Sqlcmd -Database $database -ServerInstance $server -Query "insert into $table VALUES ('$($_.FirstName)','$($_.LastName)','$($_.Department)','$($_.Title)')" 
}

因此,為了在INSERT之前先進行TRUNCATE ,我在下面測試了以下兩個腳本:

$database = 'DATABASE'
$server = 'SERVER'
$table = 'TABLE'
Import-CSV \\TESTPATH\licenses_v2.csv | 
ForEach-Object { Invoke-Sqlcmd -Database $database -ServerInstance $server -Query "truncate table $table; insert into $table VALUES ('$($_.FirstName)','$($_.LastName)','$($_.Department)','$($_.Title)')" 
}

$database = 'DATABASE'
$server = 'SERVER'
$table = 'TABLE'
Invoke-Sqlcmd -Database $database -ServerInstance $server -Query "truncate table $table"
Import-CSV \\TESTPATH\licenses_v2.csv | 
ForEach-Object { Invoke-Sqlcmd -Database $database -ServerInstance $server -Query "insert into $table VALUES ('$($_.FirstName)','$($_.LastName)','$($_.Department)','$($_.Title)')" 
}

測試完這些腳本之后,然后使用頁面頂部的原始腳本,我的表從.CSV插入中返回相同數量的記錄,但是現在它們都為空,在測試這些腳本之前不是這種情況兩個單獨的TRUNCATE腳本(該文件在每個記錄中仍具有相同的值):

在此處輸入圖片說明

從PowerShell查詢對象,看起來select-object命令現在返回所有空記錄

import-csv \\TestPath\licenses_v2.csv | select-object FirstName,Department,Title

但是, Import-CSV確實返回文件中存在的值

Import-CSV \\TestPath\licenses_v2.csv

測試其他SQL語句以插入文字SQL字符串,看來我仍然可以使用invoke-sqlcmd寫入表,但是(我可能錯了)我以某種方式截斷了powershell從文件讀取的對象值,即使這些值仍在文件中。

我需要以某種方式還原PowerShell還是以某種方式更改了文件系統?

另外,我可以使用以下腳本從SQL查詢相同的文件,因此我顯然能夠讀取值,但是由於某些原因,我的PowerShell腳本無法使用import-csv命令讀取值:

CREATE TABLE #TempTable(
    [FirstName] [varchar](50) NULL,
    [LastName] [varchar](50) NULL,
    [Department] [varchar](150) NULL,
    [Title] [varchar](150) NULL
) 
   BULK INSERT #TempTable
    FROM '\\TestPath\licenses_v2.csv'
    WITH
(
  FIRSTROW = 2,
  DATAFILETYPE='char', 
  FIELDTERMINATOR = '|',
  ROWTERMINATOR = '\n',
  TABLOCK,
  KEEPNULLS -- Treat empty fields as NULLs.
)
go
select * from #TempTable

在此處輸入圖片說明

這兩種方法都容易出錯,因為SQL注入問題很容易出現,因為您要為查詢串聯字符串。 使用參數化查詢(預備語句)會更好,因為它將避免大部分(即使不是全部)麻煩。 但這將為您編寫更多代碼。

對您來說幸運的是, dbatools PowerShell模塊可以使用Write-DbaDataTable函數來簡化此過程並使其更快,更安全,更可靠。

使用install-module dbatools (假設您使用的是PowerShell 5 / WMF5;否則,您需要按照網站上的備用安裝說明進行操作)。

import-module dbatools;
$database = 'DATABASE';
$server = 'SERVER';
$table = 'TABLE';
$MyData = import-csv \\TESTPATH\licenses_v2.csv | select-object FirstName,Department,Title;
Write-DbaDataTable -sqlinstance $server -database $database -table $table -inputobject $MyData;

如果需要首先截斷表,則可以使用-Truncate開關。

該問題是由於缺少定界符引起的。

我使用的是管道分隔的CSV,默認情況下為逗號。 我的導出腳本屏幕#1中有一個,因為它為每一列創建一個對象。 這就是標題為空的原因,因為powershell不匹配這些文字標題下的任何對象(因為只有一個標題,稱為所有標題的組合)。

請注意,如果選擇的內容與字面上沒有任何內容匹配,則Select可以返回標頭:

'' | Select Name,Date

Name Date
---- ----

要解決此問題,只需使用Import-Csv -Delimiter '|'

請參閱https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/import-csv?view=powershell-6#optional-parameters

如果您在文件中指定的字符不是實際的字符串定界符,則Import-Csv無法從CSV字符串創建對象。 而是返回字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM