OPENROWSET - как читать все как текст? - PullRequest
3 голосов
/ 10 января 2012

Я использую следующую команду для загрузки данных в SQL Server:

INSERT INTO [NewTable]

SELECT * FROM OPENROWSET 
(
'MSDASQL', 'Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\SomeFolder\;'
, 'SELECT * from [SomeFile.csv]'
);

Проблема в том, что, по-видимому, драйвер пытается угадать тип данных для каждого поля, и в случае неудачного приведения он просто читает ноль. Например, допустим, у меня есть следующее

SomeCode   SomeName
100        A
299        B
22         C
123        D
ABC        E
900        F

Кажется, что рисунок SomeCode является целым числом, и он будет читать "ABC" как NULL. Есть ли способ, которым я могу остановить это. Все, что я хочу, это чтобы данные обрабатывались как varchars на всем протяжении.

Есть идеи?

Ответы [ 4 ]

3 голосов
/ 10 января 2012

Взгляните на вторую ссылку в моем ответе на этот вопрос о ключах реестра, которые контролируют, как JET определяет типы.

Возможно, вы также захотите убедиться, что для ключа ImportMixedTypes установлено значение Text.

HKLM\Software\Microsoft\Jet\4.0\Engines\Excel\ImportMixedTypes

Возможно, вам придется заменить что-то еще на Excel.

2 голосов
/ 10 января 2012

Он будет сканировать только несколько строк, чтобы определить наиболее вероятный тип данных.Это проблема в таких сценариях, как ваш.Однако вы можете использовать файл формата вместе с OPENROWSET.

Подробная информация о том, как отформатировать FORMATFILE при чтении текстовых файлов.http://msdn.microsoft.com/en-us/library/ms191175.aspx

В вашем случае:

Создайте файл formatfile.xml, содержащий:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="," MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Col1" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="2" NAME="Col2" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>

Измените запрос на:

BULK INSERT [newTable]
FROM 'C:\somefile.csv' 
WITH (formatfile='C:\formatfile.xml');
1 голос
/ 22 ноября 2016

Мне потребовалось некоторое время, чтобы найти то, что я искал, поэтому добавьте его сюда, поскольку это один из лучших результатов:

Если вы используете Microsoft.ACE.OLEDB и столкнулись с этой проблемой, вам нужно добавить опцию «IMEX = 1;» (без кавычек) к источнику данных.

Пример:

SELECT * INTO #temp FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0 Xml;HDR=YES;IMEX=1;Database=P:\Data\FileName.xlsx' ,'SELECT * FROM [Sheet1$A1:BB100]')

Это будет читать смешанные данные в виде текста. Надеюсь, это поможет.

0 голосов
/ 03 июля 2019

ярлык для решения этой проблемы - использовать «HDR = Нет». в этом случае из-за заголовка datatType (Text) значением по умолчанию для столбцов будет текст. в конце вы можете просто отфильтровать строку заголовка. в вашем случае:

INSERT INTO [NewTable]

SELECT * FROM OPENROWSET 
(
'MSDASQL', 'Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\SomeFolder\;'
;HDR=Noe, 'SELECT * from [SomeFile.csv]'
)where [F1] <> 'SomeCode';
...