【问题标题】:SQL Server BCP: How to put quotes around all fields?SQL Server BCP:如何在所有字段周围加上引号?
【发布时间】:2011-01-04 21:21:24
【问题描述】:

我有这个 BCP 命令:

'bcp DBName..vieter out c:\test003.txt -c -T /t"\",\"" -S SERVER'

我得到的输出 CSV 没有在字段名称周围加上引号,而是在逗号周围加上引号!我怎样才能让/t"\",\"" 在所有字段周围加上引号。

谢谢大家

【问题讨论】:

    标签: sql-server csv bcp


    【解决方案1】:

    或者,如果您对基于 Powershell 的脚本没问题,您可以尝试使用下面的代码,它会自动引用。

    Invoke-sqlcmd -ConnectionString "Server=SERVERNAME, `
    3180;Database=DATABASENAME;Trusted_Connection=True;"  `
    -Query "SET NOCOUNT ON;SELECT * FROM TABLENAME" -MaxCharLength 700 | `
    Export-Csv -NoTypeInformation -path C:\temp\FileName.csv -Encoding UTF8
    

    【讨论】:

      【解决方案2】:
      bcp "SELECT char(34) + * +char(34) FROM atable queryout "C:\temp\out.csv" -T -N -c /t"\",\""
      

      这将在每个字段之前和之后加上引号(包括第一个和最后一个)。

      【讨论】:

        【解决方案3】:

        在字段终止符之外设置行终止符应该可以解决问题

        'bcp DBName..vieter out c:\test003.txt -c -T -t"\",\"" -r"\"\n\"" -S SERVER'
        

        这可能会奏效,但错过了第一行第一个字段的前导 ",也许最后一行的最后一个字段 - 我不确定,只是猜测,这里没有服务器!

        或尝试使用 QUOTENAME 包装文本字段(您也可以包装数字,但这通常不是必需的。)

        'bcp "SELECT id, age, QUOTENAME(name,'"') FROM DBName..vieter" queryout c:\test003.txt -c -T -t"," -S SERVER'
        

        【讨论】:

        • 有没有办法让第一个和最后一个引号 - 我真的需要一个格式良好的 CSV 文件。
        • 你所说的发生了 - 但最后一个字段末尾有两个引号,第一个没有引号。我只需要摆弄上面的东西就可以得到我想要的吗?是否有一些我可以查看的文档,因为我没有遇到过这个正则表达式的东西 - 如果它是正则表达式!
        • 您可以使用QUERYOUT,然后使用QUOTENAME(column,'"') 为文本字段创建查询。
        • 我可以使用 QUOTENAME 引用所有列而不传递列的名称,因为我需要为不同的表执行此操作?我试过了,但出现了很多错误——引用正确吗?我在EXEC master..xp_cmdshell @bcpCommand 中使用上述内容
        • 注意:QUOTENAME 仅支持长度不超过 128 个字符的输入字符串,因此不适用于较长的字段值。
        【解决方案4】:

        我猜你的目标是通过使用唯一标识符清楚地分隔字段值,以便导入过程没有问题。

        我遇到了同样的问题,发现这个解决方法很有用:使用不寻常的字段终止符,例如 | 甚至是字符串 /#/ 可能非常独特,不应该与您的字符串内容混淆。你也可以使用 HEX-Values(有限,见https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017

        导出

        bcp DB.dbo.Table out /tmp/output2.csv -c -t "/#/" -U sa -P secret -S localhost
        

        导入

        bcp TargetTable in /tmp/output2.csv -t "/#/" -k -U sa -P secret -S localhost -d DBNAME -c -b 50000 
        

        【讨论】:

        • 我喜欢这个解决方案,但还有另一种情况会导致麻烦。也就是说,如果在字段值中使用回车/换行。我认为需要封闭这些字段以克服这一点。
        【解决方案5】:

        这是我使用的命令列表。

        BCP "DECLARE @colnames VARCHAR(max);SELECT @colnames = COALESCE(@colnames + ',', '') + column_name from databaseName.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='tableName'; select @colnames;" queryout "C:\HeadersOnly.csv" -r"\n\""  -c -T -Uusername -Ppassword -SserverName
        
        bcp databaseName.schema.tableName out "C:\EmployeeDatawithoutheaders.csv" -T -t"\",\"" -r"\"\n\"" -c -Uusername -Ppassword -SserverName
        
        copy /b C:\HeadersOnly.csv+C:\EmployeeDatawithoutheaders.csv C:\EmployeeData.csv
        
        del C:\HeadersOnly.csv
        
        del C:\EmployeeDatawithoutheaders.csv
        

        【讨论】:

        • 真的很喜欢这个解决方案,一些增强的问题: 1. 任何避免最后一行成为“ 2. 任何聪明的选项并使用额外的” 仅当单元格包含一列 ( ,) 还是行 (\n) 分隔符?
        【解决方案6】:

        删除前导引号的实际可行答案是:

        A) 使用 bcp 生成格式文件:

        bcp db.schema.tabel format nul -c -x -f file.xml -t"\",\"" -r"\"\r\n" -T -k
        

        B) 编辑该文件以手动将字段 1 复制到上面的字段 0,作为第一个字段,设置 Max_Length=1 并删除分隔符和一个引号是在字段 1 中

        <FIELD ID="0" xsi:type="CharTerm" TERMINATOR="\&quot;" MAX_LENGTH="1" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
        

        这个技巧很有效,因为您正在添加一个字段(文件的接口)来检测第一个分隔符,这会导致始终为空值,但不会添加一行(查询输出的接口)。

        【讨论】:

          【解决方案7】:

          您需要使用 CHAR(34) 作为报价单。此页面有更多详细信息:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=153000

          【讨论】:

            猜你喜欢
            • 2022-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-21
            相关资源
            最近更新 更多