#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, чем у меня, может быть способ сделать это.