2つのデータベース間でデータを移行しています。最初のデータベースから、次の列を持つcsvファイルをエクスポートしています。
Customer_Name
Contact_First_Name
Contact_Last_Name
Phone1
Phone2
Fax
このデータを取得して、新しいデータベースの次のテーブルに配置する必要があります。
Table: customer_contact
contact_id INT IDENTITY(1,1)
first_name VARCHAR(50)
last_name VARCHAR(50)
customer_id INT
PK = contact_id
Table: contact_phone
contact_id INT
phone_num VARCHAR(15)
in_use BIT
PK = contact_id, phone_num
Table: contact_fax
contact_id INT
fax_num VARCHAR(15)
in_use BIT
PK = contact_id, fax_num
私の計画はBULK INSERT
csvからのデータを一時テーブルに格納し、それを使用して他の各テーブルにINSERT
sを実行します。
各連絡先のメインの識別子は姓と名の場合、対応するデータを電話とFAXのテーブルに挿入するにはどうすればよいですか? SQL Serverを使用しています。
このソリューションは、CSVでデータを繰り返しており、すべてのケースで何をするかを制御したい場合に適用されます。以下のフィールドについての質問には何もないので、それらのロジックは含めません。
customer_id INT,
in_use BIT
0-質問ですでに宣言したテーブルを作成します
1-cvsの正確な構造を持つt_Bulkテーブルを作成し、一括コピーを実行します
CREATE TABLE T_BULK (
Customer_Name VARCHAR(100),
Contact_First_Name VARCHAR(50),
Contact_Last_Name VARCHAR(50),
Phone1 VARCHAR(15),
Phone2 VARCHAR(15),
Fax VARCHAR(15)
);
GO
2-T_BULKテーブルがすでにいっぱいになっている状態で、各レコードを処理してみましょう。
DECLARE @ContactId int, @FirstName varchar(50), @LastName varchar(50), @Phone1 varchar(50), @Phone2 varchar(50), @Fax varchar(50)
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT Contact_First_Name, Contact_Last_Name, Phone1, Phone2, Fax
FROM dbo.T_BULK
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @FirstName, @LastName, @Phone1, @Phone2, @Fax
WHILE @@FETCH_STATUS = 0
BEGIN
//if the contact already exists we get the identity
IF EXISTS (select contact_id from customer_contact where first_name=@FirstName and last_name=@LastName)
select @ContactId = contact_id from customer_contact where first_name=@FirstName and last_name=@LastName
//if the contact does not exit we need to insert and retrieve the new Identity value
ELSE
BEGIN
insert customer_contact (first_name,last_name) values (@FirstName,@LastName)
set @ContactId = SCOPE_IDENTITY()
END
//now we continue with the phones and fax
//insert only new phones
INSERT contact_phone (contact_id,phone_num)
SELECT Id, Phone
FROM (select @ContactId as Id, @Phone1 as Phone UNION select @ContactId ,@Phone2) P
WHERE NOT EXISTS (SELECT * FROM contact_phone C WHERE C.contact_id = P.Id and C.phone_num = P.Phone);
//insert only new fax
INSERT contact_fax (contact_id,fax_num)
SELECT Id, fax
FROM (select @ContactId as Id, @Fax as fax) F
WHERE NOT EXISTS (SELECT * FROM contact_fax C WHERE C.contact_id = F.Id and C.fax_num = F.fax);
FETCH NEXT FROM MY_CURSOR INTO @FirstName, @LastName, @Phone1, @Phone2, @Fax
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
幸運を
追加フィールドを含めるには:
宣言ゾーンに追加の変数を含めます:@Extension
。
両方に含める必要がありますFETCH NEXT
行。次に、電話を挿入するときにその変数を含める必要がありますが、この場合は、電話が重複していないことを確認するために、phone2がphone1と等しくないことを確認する必要があります。
(select @contactId as Id, @Phone1 as Phone, @Extension as Extension
UNION select @ContactId, @Phone2, null where @Phone2 <>@Phone1) P
[〜#〜] bcp [〜#〜]を使用する場合は、KEEPIDENTITY
を使用する必要があります。これにより、一括挿入SQL Serverが提供する自動インクリメントではなく、既存のID値を使用します。
また、最終的なテーブルに挿入する前にステージングテーブルを使用します。これにより、データの整合性とフォーマットを検証します。
これは、CSVファイルにデータの問題がないと想定してタスクを実行する方法です。 first_name、last_nameは、個人を一意に識別すると想定します。たとえば、1人につき1行です...
1Xロード
STG_Contactsを 'c:\ contacts.csv'から一括挿入(FIELDTERMINATOR = '、'、ROWTERMINATOR = '\ n')
-customer_idを生成する方法がわからないため、デフォルトでnullにしてください
customer_contactに挿入(first_name、last_name、customer_id)STG_ContactsからCustomer_IDとしてContact_First_Name、Contact_LastName、NULLを選択します
-デフォルトの電話1からtrue電話2からfalse ??
contact_phone(contact_id、phone_num、in_use)select b.contact_id、a.Phone1、 'True' from InUse from STG_Contacts a join customer_contact b on a.Contact_First_Name = b.first_name and a.Contact_Last_Name = b.last_name where(Phone1 is not nullおよびlen(Phone1)> 0)union all select b.contact_id、a.Phone2、 'False' from InUse from STG_Contacts a join customer_contact b on a.Contact_First_Name = b.first_name and a.Contact_Last_Name = b.last_name where( Phone2はnullではなく、len(Phone2)> 0)
contact_fax(contact_id、fax_num、in_use)に挿入b.contact_id、a.fax、 'True' as InUse from STG_Contacts a join customer_contact b on a.Contact_First_Name = b.first_name and a.Contact_Last_Name = b.last_name where(fax_num is nullではなく、len(fax_num)> 0)
Nightly loading ... SSISまたはTSQLを介してSQLエージェントを介して
マージステートメントを使用して新しい行、更新、削除を処理する方法については、この link を使用してください。