我刚刚学习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)')"
}
因此,为了TRUNCATE
之前的INSERT
,我已经测试了以下两个脚本:
$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
但是,导入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
答案 0 :(得分:0)
由于您为查询连接字符串,因此两种方法都容易出错,这是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
开关。
答案 1 :(得分:0)
问题是由缺少的分隔符引起的。
我使用管道分隔的CSV,默认为逗号。我的导出脚本屏幕#1中的Theres因为它为每列创建了一个对象。这就是为什么标题为空的原因,因为powershell与这些文字标题下的任何对象都不匹配(因为那里只有一个标题,被命名为all的组合。)
请注意,Select匹配时可以返回标题:
'' | Select Name,Date
Name Date
---- ----
要修复,只需使用Import-Csv -Delimiter '|'
如果在文件中指定了除实际字符串分隔符以外的字符,则Import-Csv无法从CSV字符串创建对象。相反,它返回字符串。