patternsqlMinor
Use BCP To Copy When Data Has Apostrophe In It
Viewed 0 times
apostrophehasbcpwhenusedatacopy
Problem
Anytime my data has an apostrophe in it, the data is automatically split into the next field (which is skewing the result set). Let's say this is my DDL
And this is the
This syntax will place "Drop It Like It" in data and "s Hot" in data1 when the entire phrase should go in data and data1 should be blank.
How should I alter this procedure so that the hyphen does not cause improper splitting?
Create Table OneTwoThree
(
userid varchar(max)
,name varchar(max)
,data varchar(max)
,data1 varchar(max)
,data2 varchar(max)
)
Insert Into OneTwoThree Values
('bb12', 'Hi Blee', 'Drop It Like It''s Hot', '', 'Boop')And this is the
BCP command I am usingSelect @sql = 'bcp "SELECT ''userid'',''name'',''data'',
''data1'',''data2''
UNION ALL SELECT CAST([userid] As VARCHAR(MAX)),
CAST([name] As VARCHAR(MAX)),CAST([data] As VARCHAR(MAX)),
CAST([data1] As VARCHAR(MAX)),
CAST([data2] As VARCHAR(MAX)) dbo.OneTwoThree" queryout "'
SET @sql = @sql + 'C:\BCPTest.csv' + '" -c -t, -T -S '+ @@servername
exec master..xp_cmdshell @sqlThis syntax will place "Drop It Like It" in data and "s Hot" in data1 when the entire phrase should go in data and data1 should be blank.
How should I alter this procedure so that the hyphen does not cause improper splitting?
Solution
Presumably you are expecting the .csv file to be opened using Excel or some equivalent. I'd recommend wrapping the outputted text columns in double-quotes, such as:
The output will look similar to:
If the
At that point, you'll start to see issues with columns that contain double-quotes; however you might decide to use the
declare @sql VARCHAR(1000);
Select @sql = 'bcp.exe "SELECT ''"userid"'',''"name"'',''"data"'',
''"data1"'',''"data2"''
UNION ALL
SELECT CHAR(34) + CAST([userid] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([name] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data1] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data2] As VARCHAR(MAX)) + CHAR(34)
FROM dbo.OneTwoThree" queryout "'
SET @sql = @sql + 'C:\temp\BCPTest.csv' + '" -c -t, -T -S '+ @@servername
PRINT @sql;
exec master..xp_cmdshell @sqlThe output will look similar to:
If the
BCPTest.csv is then opened with Excel, the double-quotes will be automatically interpreted as indicating those columns are text columns, and Excel will not show the quote marks. Therefore, you only want to wrap text (CHAR, VARCHAR, NVARCHAR etc) columns in CHAR(34).At that point, you'll start to see issues with columns that contain double-quotes; however you might decide to use the
REPLACE() function to convert them into single-quotes or some other innocuous character.Code Snippets
declare @sql VARCHAR(1000);
Select @sql = 'bcp.exe "SELECT ''"userid"'',''"name"'',''"data"'',
''"data1"'',''"data2"''
UNION ALL
SELECT CHAR(34) + CAST([userid] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([name] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data1] As VARCHAR(MAX)) + CHAR(34)
, CHAR(34) + CAST([data2] As VARCHAR(MAX)) + CHAR(34)
FROM dbo.OneTwoThree" queryout "'
SET @sql = @sql + 'C:\temp\BCPTest.csv' + '" -c -t, -T -S '+ @@servername
PRINT @sql;
exec master..xp_cmdshell @sqlContext
StackExchange Database Administrators Q#140235, answer score: 4
Revisions (0)
No revisions yet.