Error converting data type varchar to numeric

Cataster 661 Reputation points
2021-01-08T21:52:31.877+00:00

I am running the following bcp command

bcp "select * from (select 'Style Code' as [Style Code], 'MY Code' as [MY Code] union select [Style Code], [MY Code] from UnPivoted_Table) q order by case [Style Code] when 'Style Code' then 0 ELSE 1 END" queryout "\\server.domain.com\CSV_Files\file1.csv" -c -t, -T -S "server1.db.com" -d "DB1"

but i am getting error:

Starting copy...
SQLState = 37000, NativeError = 8114
Error = [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Error converting data type varchar to numeric.
SQLState = S1000, NativeError = 0
Error = [Microsoft][ODBC Driver 13 for SQL Server]Unable to resolve column level collations

Now I think i know why this is happening, because one of the columns is a decimal datatype. but what can i do in this case then? Of course, casting is one option, but im afraid that when i want to reimport the resulting csv file into a table with corresponding decimal dataype columns, it will fail. I faced an issue in the past like this with a sql bulk copy script i wrote:

Exception calling "WriteToServer" with "1" argument(s): "The given value of type String from the data source cannot be converted to type real of the specified target column."

so I am trying to explore other options besides casting from decimal to varchar.

Ive seen recommendations to use "native format" and looked into it on MS Docs, but not sure if thats the right approach and how do i apply it to the above bcp command I have so far?

Developer technologies | Transact-SQL
SQL Server | Other
{count} votes

Accepted answer
  1. Cataster 661 Reputation points
    2021-01-12T20:16:42.247+00:00

    For the sake of this question context, @Guoxiong answer to cast the columns does work. However, in the grand scheme of things, this answer will be problematic when we want to reimport back to SQL, specifically because we have to deal with the header which without RN will be randomly placed in the generated file, and with RN it will be consider as an extra row...although To skip the first header row in import operation, you can specify the -F 2 option.

    SELECT [Style Code], [MY Code] FROM (SELECT 'Style Code' AS [Style Code], 'MY Code' AS [MY Code], 0 AS RN UNION SELECT CAST([Style Code] AS varchar(20)), CAST([MY Code] AS varchar(20)), 1 AS RN FROM [dbo].[UnPivoted_Table]) AS t ORDER BY RN  
    

    Therefore, @Erland Sommarskog approach/recommendation is more feasible to the requirements I have, as the goal is to export from a SQL view then reimport into an equivalent SQL table.

    The better solution therefore using bcp is as follows:

    Referencing MS Docs, follow the following steps:

    1. Create a format file of the table you plan to import into (or from the source table/view...either is fine as long as they are identical, e.g. same columns, same data types, etc.) bcp DBName.dbo.ViewOrTableName format null -f "\\...\FormatFileName.fmt" -n -T -S "sqldbserver.domain.com" If your column names contain spaces, you MUST replace them with underscore in the format file based on answer here by steve smith, otherwise you'll run into this error:

    SQLState = 22001, NativeError = 0
    Error = [Microsoft][ODBC Driver 13 for SQL Server]String data, right truncation

    1. Generate a bcp file to export the data from source table/view using the format file created in step1 bcp DBName.dbo.ViewOrTableName out "\\...\fileName.bcp" -f "\\...\FormatFileName.fmt" -T -S "sqldbserver.domain.com"
    2. Import data into new table using bcp file generated in step2 bcp DBName.dbo.TableName IN "\\...\fileName.bcp" -T -S "sqldbserver.domain.com" -n

    Note: -T is for Integrated Security, so use -U and -P options to specify username/password respectively if needed instead.
    Note2: When bulk copying to SQL Server, specify the TABLOCK bulk copy hint and set a large batch size to improve performance; you can use -h "TABLOCK" and -b switches. Ref

    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. EchoLiu-MSFT 14,621 Reputation points
    2021-01-11T07:13:20.867+00:00

    Hi @Cataster

    Do you have any updates?

    Echo

    1 person found this answer helpful.

  2. Tom Phillips 17,771 Reputation points
    2021-01-08T22:18:03.193+00:00

    Because you added a "header" row with a UNION, you must convert ALL your output to conform to that data type.

    You will be much happier if the first thing you do is run your query in SSMS. Then you can use BCP to run the query once it works.


  3. Guoxiong 8,206 Reputation points
    2021-01-08T22:26:26.357+00:00

    Use this query:

    SELECT * FROM (
    SELECT 'Style Code' AS [Style Code], 'MY Code' AS [MY Code], 0 AS RN
    UNION
    SELECT [Style Code], [MY Code], 1 AS RN FROM [dbo].[UnPivoted_Table]
    ) AS t
    ORDER BY RN
    

  4. Erland Sommarskog 121.4K Reputation points MVP Volunteer Moderator
    2021-01-08T22:28:43.93+00:00

    I have an article on my web site on using BCP and BULK INSERT. It includes an description of how you can create a file with a header without using UNION. http://www.sommarskog.se/bulkload.html


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.