#sql-server-2005
#sql-server-2005
Вопрос:
У меня есть таблица Customer, в которой содержатся сведения о клиенте. Ниже приведены поля
CustId (PrimaryKey), Name, Date of Birth
У меня есть другая таблица, информация об активе. Там находятся следующие поля —
AssetId (PrimaryKey), AssetValue, CustId (Foreign Key Reference)
Мой CSV-файл как таковой
Name, Date of Birth, AssetValue
и я должен вставить его в две таблицы. Я разделил CSV-файл, один из которых содержит имя даты рождения, а другой — только значение актива.
Вот что я сделал —
/*Creation of Table*/
CREATE TABLE Customer
(
custid int identity(1,1) not null,
name nvarchar(50) not null,
dateofbirth datetime not null,
primary key (custid)
)
CREATE TABLE Asset
(
AssetId int identity(1,1) not null,
AssetDollars money not null,
primary key (AssetId),
CustId int foreign key references Customer(custid)
)
Для массовой вставки я сделал следующее. Я создал представление для клиента с двумя полями Name и Date of Birth и затем вставил записи.
Вот что я сделал —
CREATE view vw_bulk_insert_customer
AS
SELECT name, dateofbirth FROM customer
BULK INSERT vw_bulk_insert_customer
FROM 'C:Customer.csv'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = 'n'
)
Это сработало отлично.
Теперь, как мне вставить его в таблицу активов с CustID (поскольку он недоступен в файле CSV).
Мне не разрешено изменять файл CSV. Я могу разделить CSV-файл, это разрешено.
Я не знал, как это сделать…Есть мысли?
Ответ №1:
Одним из вариантов является импорт данных как есть во промежуточную таблицу, затем копирование данных из этой таблицы в конечные таблицы. По сути, это последняя часть нормализации базы данных (пропуская дизайн и определение нормализованных таблиц).
/* interim table */
CREATE TABLE CustomerAssets (
name NVARCHAR(50) NOT NULL,
dateOfBirth DATETIME NOT NULL,
assetDollars MONEY NOT NULL
)
BULK INSERT CustomerAssets
FROM 'C:Customer.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = 'n'
)
INSERT INTO Customer (name, dateOfBirth)
SELECT name, dateOfBirth FROM CustomerAssets;
INSERT INTO Asset (assetDollars, custId)
SELECT CA.assetDollars, Customer.custId
FROM CustomerAssets AS CA
INNER JOIN Customer
ON CA.name = Customer.name AND CA.dateOfBirth = Customer.dateOfBirth;
Ответ №2:
вы можете использовать disable novalidate поверх внешнего ключа. после того, как вы импортировали все свои данные, вы можете включить novalidate поверх внешнего ключа.То же самое можно сделать и с первичным ключом. Преимущество опции novalidate заключается в том, что ваши предыдущие данные не будут проверяться в соответствии с правилами этого ограничения, но данные после него, следовательно, проверяются. если вы хотите, я мог бы вставить весь синтаксис, чтобы сделать то же самое
Комментарии:
1. Это не отвечает на вопрос, касающийся использования суррогатного ключа, когда доступен только естественный ключ.