[英]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 '|'
如果您在文件中指定的字符不是实际的字符串定界符,则Import-Csv无法从CSV字符串创建对象。 而是返回字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.