Проблема с типом данных при извлечении ADO для CSV

#sql #csv #types #ado

#sql #csv #типы #ado

Вопрос:

Хорошо, столкнулся с проблемой при извлечении почтового индекса из CSV-файла с помощью ADO. Что происходит, так это то, что если первый набор почтовых индексов имеет длину 5 цифр, тип данных присваивается как целое число для всего свойства поля в наборе записей, что не было бы проблемой, если бы следующие почтовые индексы не были 9-значным почтовым индексом с тире (99999 против 99999-9999). Когда встречаются эти 9-значные почтовые индексы, поле выдает значение null. Итак, я могу только предположить, что JET 4 берет небольшую выборку данных (первые 3 записи?) и присваивает тип данных этому полю. Я пытался установить тип поля во время выполнения, но потерпел неудачу либо потому, что я не знаю, что я делаю, либо это вне моего контроля.

Пара примечательных моментов: 1. У меня есть контроль над инструкцией SQL, которая извлекает информацию (которая использует предложение group by) 2. У меня ограниченный контроль перед извлечением данных. 3. Язык выполнения VB6, использующий ADO.

Есть предложения или указатели?

Ответ №1:

Похоже, что обычный способ сделать это — использовать файл Schema.ini:

При использовании текстового драйвера формат текстового файла определяется с помощью файла информации о схеме. Файл информации о схеме всегда называется Schema.ini и всегда хранится в том же каталоге, что и источник текстовых данных. Файл информации о схеме предоставляет IISAM информацию об общем формате файла, имени столбца и информации о типе данных, а также несколько других характеристик данных. Для доступа к данным фиксированной длины всегда требуется файл Schema.ini. Вы должны использовать файл Schema.ini, когда ваша текстовая таблица содержит данные DateTime, Currency или Decimal, или в любое время, когда вы хотите больше контролировать обработку данных в таблице.

Я настроил пример, используя следующие файлы:

test.csv:

 normal text,12345
some more ordinary words,12345-9876
  

Schema.ini

 [test.csv]
Format=CSVDelimited
ColNameHeader=False
Col1=Dummy Text
Col2=ZipCode Text
  

test.vbs

 Option Explicit

Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim oConn : Set oConn = CreateObject("ADODB.Connection")
Dim rs : Set rs = CreateObject("ADODB.Recordset")

Dim scriptPath : scriptPath = fso.GetParentFolderName(WScript.ScriptFullName)

oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" amp; scriptPath amp; ";" amp; _
           "Extended Properties=""text;HDR=NO"""

rs.Open "SELECT * FROM test.csv", oConn

WScript.Echo rs.Fields(0).Name amp; "|" amp; rs.Fields(1).Name

Do Until rs.EOF
    WScript.Echo rs.Fields(0).Value amp; "|" amp; rs.Fields(1).Value
    rs.MoveNext
Loop

rs.Close
oConn.Close
  

И результат выглядит следующим образом:

 Dummy|ZipCode
normal text|12345
some more ordinary words|12345-9876
  

Имейте в виду, что файл Schema.ini должен находиться в той же папке, что и текстовый файл, и должен ссылаться на текстовый файл по имени ( [test.csv] в примере выше). Возможно, вам придется динамически генерировать файл Schema.ini для каждого импортируемого файла или копировать и переименовывать csv-файл во временное местоположение.

Ответ №2:

Да, ADO выполняет принудительный ввод на основе первой записи. Тире ‘-‘ является недопустимым символом в целочисленном типе, поэтому он не будет их анализировать. Вы хотите, чтобы все это было строкой (на самом деле, вы делаете — почтовые индексы — это строки, а не целые числа).

Возможно, стоит подготовить данные. Напишите небольшую программу для чтения CSV и добавьте -0000 к 5-значным записям. Тогда все записи будут состоять из 10 цифр с символом — и должны быть преобразованы в строку.

Комментарии:

1. Хммм, есть какой-нибудь способ присвоить полю тип данных в виде строки перед загрузкой данных в ADO? Добавление расширенного значения -0000 выполнимо, но не является оптимальным решением.

2. Мне нужно было бы узнать больше о вашей настройке. Предполагая, что вы просто передаете имя файла csv в ADO, я не могу придумать, куда добавить обратные вызовы до того, как ADO фактически прочитает это, хотя у кого-то с большим опытом работы в ADO, чем у меня, может быть способ сделать это.