【问题标题】:BCP copy out failed -- data type conversion & column level collation errorsBCP 复制失败——数据类型转换和列级排序错误
【发布时间】:2019-11-22 13:36:20
【问题描述】:

上下文:我正在尝试通过 BCP 将 SQL Server 中表的内容输出到 CSV 文件。我正在尝试通过执行 UNION ALL 来明确命名 CSV 文件中的列标题,以便列标题不为空。

问题:有人可以分享一些关于我为什么会引发这些错误的指针,特别是当我在查询中明确转换数据类型时的数据类型转换错误?

bcp "select 'col1', 'col2', 'col3' union all select cast(id as varchar(10)), name, cast(someinfo as varchar(28)) from Question1355876" queryout myTable.csv /SmyServer01 /c /t, -T
111

我遵循了上面建议的逻辑:export table to file with column headers (column names) using the bcp utility and SQL Server 2008

下面是一直失败的T-SQL sn-p:

exec master.dbo.xp_cmdshell 'bcp "SELECT ''cast(Company_ID as int)'', ''cast(MatterMark_URL as nvarchar(150))'', ''cast(Company_Name as nvarchar(100))'', ''cast(Domain as nvarchar(150))'' UNION ALL SELECT DISTINCT cast(id as int), cast(url as nvarchar(150)), cast(company_name as nvarchar(100)), cast(domain as nvarchar(150)) FROM ##jsonparsed" queryout C:\Users\ebarnes\etl_project\company_data.csv -c -T -t'

【问题讨论】:

  • 您分享的示例显示如何包含标头,是正确的。这是一个很好的技术,但它假设所有数据类型都是兼容的。你的数据类型不是,所以你必须解决这个问题。请参阅下面的答案。此外,您使用 ''cast(Company_ID as int)'' 的原始标题语句永远不会被解释为强制转换函数,它只是作为一个大字符串一起读取。从语法上讲,它是无效的。

标签: sql-server tsql bcp


【解决方案1】:

Stu 对正在发生的事情是正确的,但需要进行一些调整,还有更多内容要添加。您遇到的错误是因为您在第二个查询中显式转换了数据类型,因此 SQL 尝试将第一个查询(隐式转换为 varchar 开始,直到 SQL 在第二个查询中遇到转换)也转换为 int。但是,第一个查询中第一列中的值无法转换为 int。它是一个 varchar 字符串“'cast(Company_ID as int)'”。

您必须使联合中的第一个和第二个查询成为相似的数据类型。您永远不会将字符串“cast(Company_ID as int)”转换为整数,我建议将第二个查询中的列转换为 char/varchar 数据类型。无论如何,您正在将数据发送到文本文件,对吗?您使用了 bcp 的 -c 选项,因此只需将第二个匹配中的所有内容都设置为第一个,反之亦然。

exec master.dbo.xp_cmdshell 'bcp "SELECT ''Company_ID'' UNION ALL SELECT DISTINCT cast(id as varchar( 12 ) ) FROM ##jsonparsed" queryout C:\Users\ebarnes\etl_project\company_data.csv -c -T -t'

【讨论】:

    【解决方案2】:

    因为Company_ID 中的值之一不是数字。喜欢标题。

    尽量不要投射它。

    【讨论】:

    • 删除所有数据转换并像这样运行查询仍然会产生相同的错误... exec master.dbo.xp_cmdshell 'bcp "SELECT ''Company_ID'', ''MatterMark_URL'', ' 'Company_Name'', ''Domain'' UNION ALL SELECT DISTINCT id,url,company_name,domain FROM ##jsonparsed" queryout C:\Users\ebarnes\etl_project\company_data.csv -c -T -t'
    • 您在这里删除的数据转换只是您最初不需要的不必要的数据转换。您在标头中拥有的“cast”函数从未被解释为函数..您将它放在文字字符串中。这就是为什么错误说它无法转换它试图转换的整个字符串的“cast(company_id as int)”。您缺少的转换是隐藏的隐式转换 SQL 正在尝试做,因为您给它 INT 值(在第二个查询中)和 varchar 值(在第一个查询中)并试图让他把它们放在同一列中。
    • 单列中只能有一种类型的数据...看到了吗? :)
    【解决方案3】:

    请试试这个

        exec master.dbo.xp_cmdshell 'bcp "SELECT DISTINCT cast(id as int) AS Company_ID, cast(url as nvarchar(150)) AS MatterMark_URL , cast(company_name as nvarchar(100)) AS Company_Name, cast(domain as nvarchar(150)) AS Domain FROM ##jsonparsed" queryout C:\Users\ebarnes\etl_project\company_data.csv -c -T -t'
    

    如果失败,则意味着您的全局临时表 ##jsonparsed 包含无法转换的无效数据。

    【讨论】:

      【解决方案4】:

      我只是将其全部转换为 nvarchar 并且我使用了一个函数,但您需要确保使用数据库名称。

      Create or alter PROCEDURE [dbo].[Export]
      AS
      BEGIN
      DECLARE @FileName varchar(50),
      @bcpCommand varchar(8000)
      SET @bcpCommand  = 'bcp "Select * from [Database].dbo.Select()" queryout "C:\temp\Output'
      + CONVERT(VARCHAR, GETDATE(), 105) + '.csv" -U[Username] -P[Password] -S.\[Instance] -r\n -w'
      PRINT @bcpCommand
      EXEC master..xp_cmdshell @bcpCommand
      END
      

      【讨论】:

        猜你喜欢
        • 2014-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多