Мне нужен обходной путь для проблемы с угадыванием типов данных в Excel

Я создаю утилиту для импорта данных из Excel в базу данных Oracle,

У меня есть фиксированный шаблон для файла excel,

Теперь, когда я пытаюсь импортировать данные с помощью провайдера Jet и инструментов подключения ADO.Net - Ole, я обнаружил следующую проблему: некоторые столбцы не были импортированы, потому что в их столбцах смешанные типы данных [string и номер],

Я искал эту проблему в Интернете и обнаружил, что причина в угадывании типов данных из Excel

Код загрузки:

connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=Excel 8.0;");
string columns = "P_ID, FULL_NAME_AR, job_no, GENDER, BIRTH_DATE, RELIGION, MARITAL_STATUS, NAT_ID, JOB_Name, FIRST_HIRE_DATE, HIRE_DATE, CONTRACT_TYPE, GRADE_CODE, QUALIFICATION";
string sheetName = "[Emps$]";
OleDbCommand command = new OleDbCommand(string.Format("select {0} from {1} where p_id is not null", columns, sheetName), connection);

connection.Open();
dr = command.ExecuteReader();
DataTable table = new DataTable();
table.Load(dr);

Что я должен сделать, чтобы сказать Excel STOP GUESSING и дать мне данные в виде текста?

если нет, можете ли вы помочь мне с какими-либо обходными путями?

заранее спасибо


person Homam    schedule 29.08.2010    source источник
comment
Как вы импортируете записи из excel в oracle? код пожалуйста? где не получается?   -  person shahkalpeshp    schedule 29.08.2010
comment
Не можете ли вы просто установить весь столбец как текст в Excel?   -  person Rup    schedule 29.08.2010
comment
@shahkalpesh: он не генерирует никаких исключений, он просто игнорирует текстовые данные, потому что он предполагает, что тип данных для столбца — это число из первых 8 записей, и возвращает null для нечисловых значений.   -  person Homam    schedule 29.08.2010
comment
Спасибо. Можете ли вы опубликовать код, который вы используете для чтения данных из Excel?   -  person shahkalpeshp    schedule 29.08.2010
comment
Обычный обходной путь для этого — создать пустую целевую таблицу и импортировать в нее вместо того, чтобы создавать таблицу каждый раз при запуске импорта. Таким образом, вы имеете полный контроль над целевыми типами данных.   -  person David-W-Fenton    schedule 30.08.2010


Ответы (4)


Я нашел решение, добавив IMEX=1 в строку подключения, но для этого есть специальный формат, который описан в следующем ссылка.

Параметр IMEX предназначен для столбцов, в которых используются смешанные числовые и буквенные значения. Драйвер Excel обычно сканирует первые несколько строк, чтобы определить, какой тип данных использовать для каждого столбца. Если столбец определяется как числовой на основе сканирования первых нескольких строк, то любые строки с буквенными символами в этом столбце будут возвращены как нулевые. Параметр IMEX (1 — режим ввода) устанавливает текстовый тип данных столбца, чтобы буквенно-цифровые значения обрабатывались правильно.

С уважением

person Homam    schedule 30.08.2010

Это не совсем правильно! По-видимому, Jet/ACE ВСЕГДА предполагает строковый тип, если первые 8 строк пусты, независимо от IMEX=1, и всегда использует числовой тип, если первые 8 строк являются числами (опять же, независимо от IMEX=1). Даже когда я заставил строки читать 0 в реестре, у меня все еще была та же проблема. Это был единственный верный способ заставить его работать:

try
{
    Console.Write(wsReader.GetDouble(j).ToString());
}
catch   //Lame unfixable bug
{
    Console.Write(wsReader.GetString(j));
}
person jbrumbaugh    schedule 16.07.2012
comment
Все зависит от того, вносили ли вы изменения в реестр или нет, в частности TypeGuessRows msdn.microsoft.com/en-us/library/bb177610(v=office.12).aspx - person Fionnuala; 17.07.2012
comment
попробуйте использовать wsReader.GetValue(j).ToString(), а затем, если вы хотите, чтобы он был двойным, вы можете попытаться проанализировать его из строки. - person Jim; 18.07.2012
comment
Проблема с этим, Джим, заключается в том, что если ваши первые значения в столбце являются числами, но позже у вас есть такие значения, как CDF62738, эти значения будут приняты как NULL, потому что недопустимое число:/ - person tomasofen; 17.12.2015

Можете ли вы работать с конца Excel? Этот пример, запущенный в Excel, поместит смешанные данные в таблицу SQL Server:

Dim cn As New ADODB.Connection

scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& sFullName _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"

cn.Open scn

s = "SELECT Col1, Col2, Col3 INTO [ODBC;Description=TEST;DRIVER=SQL Server;" _
& "SERVER=Some\Instance;Trusted_Connection=Yes;" _
& "DATABASE=test].TableZ  FROM [Sheet1$]"
cn.Execute s
person Fionnuala    schedule 29.08.2010
comment
Спасибо Рему, но это не подходит для моего случая, но у меня вопрос, почему я не могу использовать IMEX=1 в ADO.Net? и работает ли аналогичное свойство расширения с ADO.Net? - person Homam; 29.08.2010
comment
Почему нельзя использовать IMEX=1? Это просто часть строки подключения. В этом pcreview.co.uk/forums/thread-1863969.php, Павел, MVP, подскажи, что можно. - person Fionnuala; 29.08.2010
comment
@ Remou: Большое спасибо, все работает, нужно было (char)34 в строке подключения (из ссылки, которую вы добавили). - person Homam; 30.08.2010
comment
@Homam Обратите внимание, что микс должен начинаться до значения TypeGuessRows в разделе реестра: Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/, если только вы не хотите установить для TypeGuessRows значение 0, что означает, что все строки будут сканироваться. - person Fionnuala; 30.08.2010

Альтернативное решение — добавить или изменить параметр TypeGuessRows в реестре. Если установить его значение равным 0, будет отсканирован весь документ.

К сожалению, настройки могут быть найдены в разных местах реестра, в зависимости от того, какие библиотеки и их версии вы установили.

Например: [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel] "TypeGuessRows"=dword:00000000

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel] "TypeGuessRows"=dword:00000000

Это также предотвратит усечение текстовых данных длиннее 255 символов. Это происходит, если у вас есть число для TypeGuessRows больше 0 и первый текст длиннее 255 символов находится за пределами этого числа.

См. также Настройка TypeGuessRows для драйвера Excel ACE.

person R. Schreurs    schedule 07.12.2018