मेरे पास बहुत से स्तंभों वाली एक पुरानी तालिका है जिसे मैं 3 तालिकाओं में विभाजित करना चाहता हूं जिसमें कई से कई संबंध हैं।

पुरानी तालिका में कोई पहचान स्तंभ नहीं है।

पुरानी मेज:

CustomerNumber
FirstName
LastName
Address
Postal
City
....

नई टेबल

ग्राहक:

Id
Customernumber
Firstname
Lastname
... ect

पता:

Id
Address
Postal
City
... ect

ग्राहक का पता

Id
CustomerId
AddressId

अब मैं SQL का उपयोग करके पुराने टेबल को नए में कैसे फैला सकता हूं?

मैंने मेर्ज के साथ प्रयास किया है लेकिन वह उस समय एक से अधिक टेबल को संभाल नहीं सकता है। एक विकल्प कर्सर का उपयोग कर रहा है, लेकिन मैंने पढ़ा है कि यह एक बुरा विचार है, उस या पुनरावृत्ति का उपयोग करना, लेकिन अभी के लिए यही एकमात्र समाधान है जो मुझे इसके लिए मिला है।

declare 
@CustomerId bigint,
@CustomerNumber float, 
@Status int,
@Address varchar(50),
@RoadNumber int,
@LastEdited datetime,

@AddressId bigint

declare my_cursor cursor
local static read_only forward_only
for
    select CustomerNumber, Address, Housenumber, Status, Date
    from [db1].dbo.OldCustomer k
    where 
        FIRMANR in (1, 40, 60, 80, 90, 120, 180, 400)

    open my_cursor
    fetch next from my_cursor into @CustomerNumber, @Address, @RoadNumber, @Status, @LastEdited
while @@FETCH_STATUS = 0
begin
    --if the customer already exists we get the identity
    if exists (select Id from [db2].dbo.Customers where CustomerNumber = @CustomerNumber)
        select @CustomerId = Id from [db2].dbo.Customers where CustomerNumber = @CustomerNumber

    --if the customer does not exit we need to insert and retrieve the new Identity value
    else
        begin
            -- insert the customer
            insert into [db2].dbo.Customers (CustomerNumber, [Status], LastEdited) values (@CustomerNumber, @Status, @LastEdited)
            set @CustomerId = SCOPE_IDENTITY()
        end

    -- get address if it already exists
    if exists (select Id from [db2].dbo.Addresses where Road = @Address and Roadnumber = @RoadNumber)
        select @AddressId = Id from [db2].dbo.Addresses where Road = @Address and Roadnumber = @RoadNumber
    else
        begin
            -- insert new addresses
            insert into [db2].dbo.Addresses (Road,Roadnumber) values (@Address, @RoadNumber)
            set @AddressId = SCOPE_IDENTITY()
        end

    -- insert customer => address reference if it does not exist
    if not exists (select Id from [db2].dbo.CustomerAddress where CustomerId = @CustomerId and AddressId = @AddressId)
        -- insert customer => address reference
        insert into [db2].dbo.CustomerAddress(CustomerId,AddressId) values (@CustomerId, @AddressId)


    fetch next from my_cursor into @CustomerNumber, @Address, @RoadNumber, @Status, @LastEdited
end

close my_cursor
deallocate my_cursor
0
Martin Overgaard 10 जिंदा 2019, 15:13

1 उत्तर

सबसे बढ़िया उत्तर

यह शायद सबसे आसान होगा:

  • AddressId नामक पुराने ग्राहक में एक कॉलम जोड़ें
  • इसे अद्वितीय आईडी से भरें (आप ग्राहक आईडी का पुन: उपयोग कर सकते हैं, या यदि इसका GUID है, तो NewID () का उपयोग करें)
  • पते और ग्राहक के पते के लिए नई तालिकाएँ बनाएँ
  • पुराने ग्राहक डेटा का हिस्सा प्रत्येक नई तालिका में डालें
  • पते से संबंधित ग्राहक से कॉलम ड्रॉप करें

--populate new Address table
INSERT INTO Address(id,col1,col2...)
SELECT AddressID, col1, col2... FROM Customer

--populate new CustomerAddress table
INSERT INTO CustomerAddress(CustomerId,AddressId)
SELECT Id, AddressID FROM Customer

एसक्यूएलएस के साथ आप इसे एक साधारण स्क्रिप्ट के रूप में कर सकते हैं, यदि आप चाहें तो लेनदेन के साथ .. संग्रहीत प्रक्रियाओं, कर्सर, विलय इत्यादि की कोई आवश्यकता नहीं है ..

CustomerAddress को उसका अपना Id कॉलम न दें; CustomerAddress की प्राथमिक कुंजी CustomerId और AddressId का संयोजन है; एक समग्र पीके बनाएं, अलग नहीं

टीबीएच, शायद मेरे पास ग्राहक पता तालिका नहीं होगी और इसके बजाय ग्राहक में बिलिंग एड्रेस आईडी, वर्कएड्रेस आईडी, होम एड्रेस आईडी, शिपिंग एड्रेस आईडी कॉलम होगा, लेकिन यह आप पर निर्भर है कि इसे कैसे प्रबंधित किया जाए; यदि आपके पास बहुत सारे और परिवर्तनशील प्रकार के पते हैं, तो निश्चित रूप से, एक M:M ब्रेकडाउन है, लेकिन यदि वास्तविक रूप से आपके ग्राहकों के पास केवल 3 पते आदि होने जा रहे हैं, तो मैं एक नामित कॉलम के साथ यह बताऊंगा कि पता क्या था के लिए, ग्राहक में

यदि आप CustomerAddress तालिका के साथ जाते हैं, तो पते के प्रकार/कारण की घोषणा करने वाला एक कॉलम जोड़ने पर विचार करें

0
Caius Jard 10 जिंदा 2019, 15:32