Объемная вставка со столбцом identity (auto-increment)
Я пытаюсь добавить данные в базу данных из файла CSV.
таблица сотрудников имеет столбец ID
(PK) автоматическое увеличение.
CREATE TABLE [dbo].[Employee](
[id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
[Address] [varchar](50) NULL
) ON [PRIMARY]
Я использую этот запрос:
BULK INSERT Employee FROM 'pathtempFile.csv '
WITH (FIRSTROW = 2,KEEPIDENTITY,FIELDTERMINATOR = ',' , ROWTERMINATOR = 'n');
.CSV файл -
Name,Address
name1,addr test 1
name2,addr test 2
но это приводит к этому сообщению об ошибке:
ошибка преобразования данных массовой загрузки (несоответствие типа или недопустимый символ для указанной кодовой страницы) для строки 2, столбец 1 (id).
7 ответов
не массовая вставка в ваш реальные таблицы напрямую.
Я всегда
- вставить в постановка таблица
dbo.Employee_Staging
(безIDENTITY
столбец) из файла CSV - возможно редактировать / очищать / манипулировать импортированными данными
-
а затем скопируйте данные в реальную таблицу с помощью оператора T-SQL, например:
INSERT INTO dbo.Employee(Name, Address) SELECT Name, Address FROM dbo.Employee_Staging
добавьте столбец id в csv-файл и оставьте его пустым:
id,Name,Address
,name1,addr test 1
,name2,addr test 2
удалить ключевое слово KEEPIDENTITY из запроса:
BULK INSERT Employee FROM 'path\tempFile.csv '
WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');
поле id identity будет автоматически увеличено.
Если вы назначаете значения полю id в csv, они будут игнорироваться, если вы не используете ключевое слово KEEPIDENTITY, то они будут использоваться вместо автоматического приращения.
у меня была аналогичная проблема, но мне нужно было убедиться, что порядок идентификатора выравнивается с порядком в исходном файле. Мое решение использует представление для массовой вставки:
сохраните таблицу как есть и создайте это представление (выберите все, кроме столбца ID)
CREATE VIEW [dbo].[VW_Employee]
AS
SELECT [Name], [Address]
FROM [dbo].[Employee];
ваша объемная вставка должна выглядеть так:
BULK INSERT [dbo].[VW_Employee] FROM 'path\tempFile.csv '
WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');
вы должны сделать массовую вставку с файлом формата:
BULK INSERT Employee FROM 'path\tempFile.csv '
WITH (FORMATFILE = 'path\tempFile.fmt');
где формат файла (tempFile.дрм) выглядит так:
11.0
2
1 SQLCHAR 0 50 "\t " 2 имя SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 50 "\r\n " 3 Адрес SQL_Latin1_General_CP1_CI_AS
подробнее здесь -http://msdn.microsoft.com/en-us/library/ms179250.aspx
мое решение-добавить поле ID в качестве последнего поля в таблице, таким образом, bulk insert игнорирует его и получает автоматические значения. Чисто и просто ...
например, при вставке во временную таблицу:
CREATE TABLE #TempTable
(field1 varchar(max), field2 varchar(max), ...
ROW_ID int IDENTITY(1,1) NOT NULL)
отметим, что ROW_ID
поле всегда должно быть указано как последнее поле!
другой вариант, если вы используете временные таблицы вместо промежуточных таблиц, может заключаться в создании временной таблицы, как ожидает ваш импорт, а затем добавьте столбец идентификаторов после импорта.
Итак, ваш sql делает что-то вроде этого:
- если временная таблица существует, drop
- создать временную таблицу
- массовый импорт в таблицу temp
- Alter temp table добавить идентификатор
- Drop temp table
все еще не очень чистый, но это еще один вариант... возможно, придется сделать замки безопасными.
у меня была точно такая же проблема, которая сделала часы потерь, поэтому я вдохновлен поделиться своими выводами и решениями, которые сработали для меня.
1. Используйте файл excel
это подход, который я принял. Вместо использования csv-файла я использовал файл excel (.XLSX) с содержанием, как показано ниже.
id username email token website
johndoe johndoe@divostar.com divostar.com
bobstone bobstone@divosays.com divosays.com
обратите внимание, что столбец id не имеет значения.
затем подключитесь к своей БД с помощью Microsoft SQL Server Management Studio и щелкните правой кнопкой мыши база данных и выберите Импорт данных (подменю в разделе задача). Выберите Microsoft Excel в качестве источника. Когда вы прибудете на этап под названием "выберите исходные таблицы и представления", нажмите изменить сопоставления. Для id
столбец под пунктом назначения, нажмите на него и выберите игнорировать . Не проверяйте Enable Identity insert
если вы не хотите, чтобы mantain ids инкассации, где вы импортируете данные из другой базы данных и хотели бы сохранить автоматический приращение id исходной БД. Продолжайте до конца, и все. Ваш данные будут импортированы плавно.
2. Использование файла CSV
в файле csv убедитесь, что ваши данные, как показано ниже.
id,username,email,token,website
,johndoe,johndoe@divostar.com,,divostar.com
,bobstone,bobstone@divosays.com,,divosays.com
выполнить запрос ниже:
BULK INSERT Metrics FROM 'D:\Data Management\Data\CSV2\Production Data 2004 - 2016.csv '
WITH (FIRSTROW = 2, FIELDTERMINATOR = ',', ROWTERMINATOR = '\n');
проблема с этим подходом заключается в том, что CSV должен быть на сервере БД или в какой-то общей папке, к которой БД может иметь доступ, иначе вы можете получить ошибку, например "не удается открыть файл. Операционная система вернула код ошибки 21 (устройство не готовый.")
если вы подключаетесь к удаленной базе данных, вы можете загрузить CSV в каталог на этом сервере и ссылаться на путь в bulk insert.
3. Использование CSV-файла и опции импорта Microsoft SQL Server Management Studio
запустите данные импорта, как в первом подходе. Для источника выберите источник "плоский файл" и выбрать файл CSV. Убедитесь, что правое меню (Общие, столбцы, дополнительно, предварительный просмотр) в порядке. Обязательно установите правильный разделитель в меню столбцы (column delimiter). Как и в подходе excel выше, нажмите изменить сопоставления. Для столбца id в пункте назначения нажмите на него и выберите игнорировать .
продолжить, чтобы закончить, и все. Ваши данные будут импортированы плавно.