SORU
19 Mart 2011, CUMARTESİ


Kullanarak..çıkış arasında kaynak eşleme elde etmek için birleştirme.kimliği ve hedef.kimliği

Çok basit, iki tablo Kaynak ve Hedef var.

declare @Source table (SourceID int identity(1,2), SourceName varchar(50))
declare @Target table (TargetID int identity(2,2), TargetName varchar(50))

insert into @Source values ('Row 1'), ('Row 2')

Ben istiyorum hareket tüm satırlar @Source @Target ve TargetID her SourceID çünkü orada da tablolar SourceChild TargetChild bu ihtiyaçları da kopyalanacak de ihtiyacım eklemek için yeni TargetID TargetChild.TargetID FK sütun.

Bunun için birkaç çözüm yolu var.

  1. Bir süre döngü veya imleç bir anda Hedef için bir satır (RBAR) takın ve scope_identity() TargetChild FK doldurmak için kullanın.
  2. @Target SourceID eklemek için geçici bir sütun ekleyin. Sonra o sütun TargetChild FK TargetID almak için katılabilirsiniz.
  3. 22 ** ve atama yeni değerleri ele kendin için SET IDENTITY_INSERT OFF. Daha sonra TargetChild.TargetID kullanan bir yelpazede olsun.

Hiçbirine düşkün olan ben değilim. Ben eskiden bu kadar çok imleçler.

Asıl yapmak istediğim şey ınsert deyim output yan kullanmaktır.

insert into @Target(TargetName)
output inserted.TargetID, S.SourceID
select SourceName
from @Source as S

Ama bu mümkün değil

The multi-part identifier "S.SourceID" could not be bound.

Ama bir birleştirme ile mümkündür.

merge @Target as T
using @Source as S
on 0=1
when not matched then
  insert (TargetName) values (SourceName)
output inserted.TargetID, S.SourceID;

Sonuç

TargetID    SourceID
----------- -----------
2           1
4           3

Eğer bu kullandıysanız bilmek istiyorum? Çözüm hakkında herhangi bir düşünce veya herhangi bir sorun görürseniz? Basit senaryolarda gayet iyi çalışıyor ama belki bir şeyler çirkin sorgu planı çok karmaşık bir kaynak sorgu nedeniyle karmaşık bir zaman olabilir. Sourceıd çift/Targetıd aslında bir maç değil bu en kötü senaryo olur.

MSDN bu output maddesi from_table_name ne diyecek?

Tablo FROM yan tümce dahil SİL belirten bir sütun öneki, UPDATE veya satır silme belirtmek için kullanılan deyim, BİRLEŞTİRME.

Nedense söylemiyorlar "eklemek, güncellemek veya silmek için satır" tek "satır güncelleştirme veya silme".

Herhangi bir düşünce bekliyoruz ve asıl sorun çok daha farklı çözümler için çok teşekkür ederiz.

CEVAP
20 Mart 2011, Pazar


Bence bu BİRLEŞTİRME ve çıkış bulunur. Birkaç senaryo kullanılmış ve bugüne kadar herhangi bir tuhaflıklar deneyimli değilim. Örneğin, burada yeni oluşturulan bir Klasör (guıd) içinde bir Klasör ve tüm Dosyaları (kimlik) klonlar bu test düzeneği.

DECLARE @FolderIndex TABLE (FolderId UNIQUEIDENTIFIER PRIMARY KEY, FolderName varchar(25));
INSERT INTO @FolderIndex 
    (FolderId, FolderName)
    VALUES(newid(), 'OriginalFolder');

DECLARE @FileIndex TABLE (FileId int identity(1,1) PRIMARY KEY, FileName varchar(10));
INSERT INTO @FileIndex 
    (FileName)
    VALUES('test.txt');

DECLARE @FileFolder TABLE (FolderId UNIQUEIDENTIFIER, FileId int, PRIMARY KEY(FolderId, FileId));
INSERT INTO @FileFolder 
    (FolderId, FileId)
    SELECT  FolderId, 
            FileId
    FROM    @FolderIndex
    CROSS JOIN  @FileIndex;  -- just to illustrate

DECLARE @sFolder TABLE (FromFolderId UNIQUEIDENTIFIER, ToFolderId UNIQUEIDENTIFIER);
DECLARE @sFile TABLE (FromFileId int, ToFileId int);

-- copy Folder Structure
MERGE @FolderIndex fi
USING   (   SELECT  1 [Dummy],
                    FolderId, 
                    FolderName
            FROM    @FolderIndex [fi]
            WHERE   FolderName = 'OriginalFolder'
        ) d ON  d.Dummy = 0
WHEN NOT MATCHED 
THEN INSERT 
    (FolderId, FolderName)
    VALUES (newid(), 'copy_' FolderName)
OUTPUT  d.FolderId,
        INSERTED.FolderId
INTO    @sFolder (FromFolderId, toFolderId);

-- copy File structure
MERGE   @FileIndex fi
USING   (   SELECT  1 [Dummy],
                    fi.FileId, 
                    fi.[FileName]
            FROM    @FileIndex fi
            INNER
            JOIN    @FileFolder fm ON 
                    fi.FileId = fm.FileId
            INNER
            JOIN    @FolderIndex fo ON 
                    fm.FolderId = fo.FolderId
            WHERE   fo.FolderName = 'OriginalFolder'
        ) d ON  d.Dummy = 0
WHEN NOT MATCHED 
THEN INSERT ([FileName])
    VALUES ([FileName])
OUTPUT  d.FileId,
        INSERTED.FileId
INTO    @sFile (FromFileId, toFileId);

-- link new files to Folders
INSERT INTO @FileFolder (FileId, FolderId)
    SELECT  sfi.toFileId, sfo.toFolderId
    FROM    @FileFolder fm
    INNER
    JOIN    @sFile sfi ON  
            fm.FileId = sfi.FromFileId
    INNER
    JOIN    @sFolder sfo ON 
            fm.FolderId = sfo.FromFolderId
-- return    
SELECT  * 
FROM    @FileIndex fi 
JOIN    @FileFolder ff ON  
        fi.FileId = ff.FileId 
JOIN    @FolderIndex fo ON  
        ff.FolderId = fo.FolderId

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • kimaliz

    kimaliz

    18 Temmuz 2006
  • manadude21

    manadude21

    11 Mart 2008
  • Vortez

    Vortez

    27 Temmuz 2009