【问题标题】:How to import data from .csv in SQL Server using PowerShell? - problem如何使用 PowerShell 从 SQL Server 中的 .csv 导入数据? - 问题
【发布时间】:2021-09-06 11:52:25
【问题描述】:

我正在尝试使用 PowerShell 将 CSV 导入 SQL Server 数据库。这就是我正在做的:

$database="myTestDB"
$server="TEST_SERVER"
$table="LOG_TEST"
Import-CSV C:\test\OUTPUT3.csv | ForEach-Object {Invoke-Sqlcmd -Database $database -ServerInstance $server -Query "INSERT INTO $table VALUES ('$($_.col1)',$($_.col2),'$($_.col3)')"}

但我不断收到此错误:

Invoke-Sqlcmd : Incorrect syntax near ','.
At line:1 char:57
+ ... ach-Object {Invoke-Sqlcmd -Database $database -ServerInstance $server ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

Col2 是一个整数。我尝试了不同的方法和符号从 CSV 中获取变量,但总是出现类似的错误。

任何帮助都会很棒。我一直在关注这个问题的答案......

How to import data from .csv in SQL Server using PowerShell?

谢谢!

更多信息:

我已经改变了一些东西以简化场景,所以我可以在这里提供更多细节。该表由 3 个 varchar 列组成。我相信最初的错误是由于数据的一些问题。我正在使用的数据文件保存为 test.csv:

col1,col2,col3
a,b,c
1,2,3
d,e,f
4,5,6
g,h,i
7,8,9

我的脚本是:

$database="myTestDB"
$server="Test_Server"
$table="csvLoadTest"
$Query="INSERT INTO $table VALUES ('$($_.col1)','$($_.col2)','$($_.col3)')"
Import-CSV C:\Test_Server\test.csv | ForEach-Object {Invoke-Sqlcmd -Database $database -ServerInstance $server -Query $Query}

我现在遇到的问题是这些字段是空白的。它运行并插入记录,但字段中没有数据。

附带说明...我知道这会带来 SQL 注入风险,但这对我来说并不是一个真正的问题,在此设置中,出于多种原因。我只是想让它在这一点上工作。谢谢!

【问题讨论】:

  • 你会遇到这样的 SQL 注入问题。你可以通过-Variables。考虑使用bcpWrite-SqlTableData
  • 运行它,看看它给出了什么:Import-CSV C:\test\OUTPUT3.csv | ForEach-Object {"INSERT INTO $table VALUES ('$($_.col1)',$($_.col2),'$($_.col3)')"}
  • 没有样本数据,这里大家只是猜测
  • 使用您的原始脚本。您不能在 ForEach-Object 之外使用 $_。您还可以在循环内移动 $Query 的定义。
  • @Jim 你熟悉“接受”答案吗?

标签: sql sql-server powershell


【解决方案1】:

这几乎可以肯定是由于您的某个字段中的逗号。

因此,如果您的数据如下所示:

HM The Queen, Buckingham Palace London, 4

,那么你有三列,对吧?

但如果你有;

HM The Queen, "Buckingham Palace, London", 4

,那你有三个还是四个?我的猜测是,col2 现在设置为 London",因为 col1 中有一个逗号,因此您会收到错误消息。

尝试使用来自http://dbatools.io 的 Import-DbaCSV 之类的东西,它非常了解这种类型的东西。并且直接推入数据库,而不是构造insert语句,避免sql注入。

【讨论】:

  • 不...我减少了我正在做的事情... $database="myTestDB" $server="TestServer" $table="TEST_TABLE" $Query="INSERT INTO $table (Body, NumSegments,direction) VALUES ('$_.body',$numSegments,'$_.direction')" Import-CSV C:\test\OUTPUT3_reform.csv | ForEach-Object {Invoke-Sqlcmd -Database $database -ServerInstance $server -Query $Query} 并且我的 CSV 的内容是字面意思:body,numSegments,direction a,3,c 在记事本中查看时错误是:Invoke-Sqlcmd : ',' 附近的语法不正确。在 line:1 char:64
  • 好的。我对这个问题发表了评论。如果你能提供,它可能会告诉你问题出在哪里。
  • “我认为最初的错误是由于数据的某些问题造成的”
【解决方案2】:

您的脚本有效,我能够使用它加载数据。
如果不发布示例文件,我们将无法找到错误,这只是猜测。 我同意其他 cmet 的观点,即它不安全(容易注射)且速度慢。
我加载的示例文件:

col1,col2,col3
aaaa,123,asdad
bbbb,3,asdad

所以猜猜它为什么会坏:

  1. 文件中的列名与 col1、col2、col3 不同
  2. 有些值为空

在这两种情况下,您都会得到与帖子中描述的完全相同的错误

【讨论】:

    【解决方案3】:

    管道 (|) 是在命令行上推送内容的好方法。在文件中,最好不要使用它,而是以更清晰易读的方式构造代码。

    我在 SQL Server 上创建了一些示例数据和一个表并测试了您的脚本。我看到了同样的错误。

    这个脚本不会产生同样的错误。运行脚本后,所有记录都会出现在数据库中。

    $database="myTestDB"
    $server="TEST_SERVER"
    $table="LOG_TEST"
    $csv="C:\test\OUTPUT3.csv"
    $data=Import-CSV -LiteralPath $csv
    ForEach ($rec in $data) {
        $qry="INSERT INTO $table VALUES('$($rec.col1)',$($rec.col2),'$($rec.col3)')"
        Invoke-Sqlcmd -Database $database -ServerInstance $server -Query $qry
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 2017-01-16
      • 2014-03-22
      • 1970-01-01
      相关资源
      最近更新 更多