2008-09-30 20 views
15

Tablodaki yeni satırların kimliklerini kopyalandıklarıyla ilişkilendirmek için bir eşleme tablosu oluşturmaya çalışıyorum. OUTPUT INTO cümlesi bunun için mükemmel görünüyor, ancak belgelere göre davranmıyor gibi görünüyor.OUTPUT INTO deyiminde hangi sütunlar kullanılabilir?

Kodum: Hata iletisinde

DECLARE @Missing TABLE (SrcContentID INT PRIMARY KEY) 
INSERT INTO @Missing 
    (SrcContentID) 
SELECT cshadow.ContentID 
    FROM Private.Content AS cshadow 
    LEFT JOIN Private.Content AS cglobal ON cshadow.Tag = cglobal.Tag 
    WHERE cglobal.ContentID IS NULL 

PRINT 'Adding new content headers' 
DECLARE @Inserted TABLE (SrcContentID INT PRIMARY KEY, TgtContentID INT) 
INSERT INTO Private.Content 
    (Tag, Description, ContentDate, DateActivate, DateDeactivate, SortOrder, CreatedOn, IsDeleted, ContentClassCode, ContentGroupID, OrgUnitID) 
    OUTPUT cglobal.ContentID, INSERTED.ContentID INTO @Inserted (SrcContentID, TgtContentID) 
SELECT Tag, Description, ContentDate, DateActivate, DateDeactivate, SortOrder, CreatedOn, IsDeleted, ContentClassCode, ContentGroupID, NULL 
    FROM Private.Content AS cglobal 
    INNER JOIN @Missing AS m ON cglobal.ContentID = m.SrcContentID 

Sonuçlar:

Msg 207, Level 16, State 1, Line 34 
Invalid column name 'SrcContentID'. 

(hat 34 ÇIKIŞ INTO bir kez olmak üzere)

Deneme satırları aslında olduklarını düşündürmektedir INSERT hedefinde mevcut OUTPUT INTO içinde seçilebilir. Ancak bu, çevrimiçi kitaplarda bulunan dokümanlar ile çelişir. Ürün tablodan ayrıca, maddenin döner içine

ÇIKIŞ Tablo (WorkOrder) güncelleştirilmesini değer verir ve: ÇIKIŞ Madde ilgili makale, örneğin, benzer bir kullanımını açıklar E yer alır. Ürün tablosu güncelleştirmesi için satırları belirtmek üzere FROM yan tümcesinde kullanılır.

Bu özellikte herhangi biri çalıştı mı?

(Bu arada ben imleç döngü kullanarak iş yapmak için kodumu yeniden kaleme aldık, ama bu çirkin ve hala merak ediyorum) Ben sorun yalnızca kullanabileceğiniz doğruladık

cevap

13

INSERTED sütun. Belgelere from_table_name kullanabilirsiniz belirtmek görünüyor, ama işe almak gibi olamaz (çok parçalı tanımlayıcı "m.ContentID" bağlı edilemedi.): Görünüşe

TRUNCATE TABLE main 

SELECT * 
FROM incoming 

SELECT * 
FROM main 

DECLARE @Missing TABLE (ContentID INT PRIMARY KEY) 
INSERT INTO @Missing(ContentID) 
SELECT incoming.ContentID 
FROM incoming 
LEFT JOIN main 
    ON main.ContentID = incoming.ContentID 
WHERE main.ContentID IS NULL 

SELECT * 
FROM @Missing 

DECLARE @Inserted TABLE (ContentID INT PRIMARY KEY, [Content] varchar(50)) 
INSERT INTO main(ContentID, [Content]) 
OUTPUT INSERTED.ContentID /* incoming doesn't work, m doesn't work */, INSERTED.[Content] INTO @Inserted (ContentID, [Content]) 
SELECT incoming.ContentID, incoming.[Content] 
FROM incoming 
INNER JOIN @Missing AS m 
    ON m.ContentID = incoming.ContentID 

SELECT * 
FROM @Inserted 

SELECT * 
FROM incoming 

SELECT * 
FROM main 

from_table_name önek sadece (2008 veya MERGE) DELETE veya UPDATE izin verilir - emin değilim neden:

  • from_table_name

bir colu mı Güncellenecek veya silinecek satırları belirtmek için kullanılan DELETE veya UPDATE ifadesinin FROM deyiminde yer alan bir tabloyu belirten mn öneki.

Değiştirilmekte olan tablo FROM maddesinde de belirtilmişse, bu tablodaki sütunlara yapılan herhangi bir başvuru, INSERTED veya önekiyle nitelendirilmelidir.

6

Sizinle aynı sorunu EXACTLY koşuyorum, acınızı hissediyorum ... Bir INSERT ifadesiyle from_table_name önekini kullanmanın bir yolu olmadığını öğrendim. Eminim bunun için geçerli bir teknik neden var ve tam olarak ne olduğunu bilmek isterim.

Tamam, buldum, işte çalışmıyor neden bir forum sonrası var: Ben bu sorun için bir çözüm buldum MSDN forums

+0

Ve bu çözümün ipucunu sağlar. MERGE ifadesi! Sonra @Simon sentaks sağlamayı başardı. Güzel! – lambacck

0

, ne yazık ki geçici bir tablo içerir, ama en azından olacak Korkunç bir imlecin oluşturulmasını engelleyin :) Yapmanız gereken, kayıtları kopyaladığınız tabloya fazladan bir sütun eklemek ve 'uniqueidentifer' türü vermek.

DECLARE @tmptable TABLE (uniqueid uniqueidentifier, original_id int, new_id int) 

bu gibi geçici tabloya veri eklemek:

insert into @tmptable 
(uniqueid,original_id,new_id) 
select NewId(),id,0 from OriginalTable 

orijinal tabloya devam edin ve gerçek ekleme yapmak:

sonra geçici bir tablo beyan

insert into OriginalTable 
(uniqueid) 
select uniqueid from @tmptable 

Şimdi yeni oluşturulan kimlik değerlerini geçici tablonuza eklemek için:

update @tmptable 
set new_id = o.id 
from OriginalTable o inner join @tmptable tmp on tmp.uniqueid = o.uniqueid 

Şimdi

+1

Teşekkürler, ancak izlemem gereken anahtar benzersiz bir tanımlayıcı ise bu sadece geçerli bir çözümdür. Çözmeyi denediğim sorunun tamamı, yeni bir satıra tahsis edilen IDENTITY değerini takip etmektir. –

0

(MS) sizin kullanarak zevk :) Bu birilerini yardımcı olur umarım

için, bir kayıtta yeni kimliği ve özgün kimliği tutan bir arama tablosu var ... Değiştirilen tablo FROM yan tümcesinde de belirtilirse, bu tablodaki sütunlara yapılan başvuru, INSERTED veya DELETED öneki ile nitelendirilmelidir. Bu gibi benim için çalıştı Ne

INSERT INTO Private.Content 
    (Tag) 
    OUTPUT cglobal.ContentID, INSERTED.ContentID 
    INTO @Inserted (SrcContentID, TgtContentID) 
SELECT Tag 
    FROM Private.Content AS cglobal 
    INNER JOIN @Missing AS m ON cglobal.ContentID = m.SrcContentID 

basit takma tablo oldu: o INSERTED.column_name veya DELETED.column_name sürece sizin örnekte

, sen ÇIKIŞ içinde cglobal tabloyu kullanamazsınız

INSERT INTO con1 
    (Tag) 
    OUTPUT **con2**.ContentID, INSERTED.ContentID 
    INTO @Inserted (SrcContentID, TgtContentID) 
SELECT Tag 
    FROM Private.Content con1 
    **INNER JOIN Private.Content con2 ON con1.id=con2.id** 
    INNER JOIN @Missing AS m ON con1.ContentID = m.SrcContentID 
Sen 2008. Örnek kod aşağıda Sql Server bir MERGE ile yapabilirsiniz
+0

Bu yaklaşımı işe yaramazdım :-( –

21

:

--drop table A 
create table A (a int primary key identity(1, 1)) 
insert into A default values 
insert into A default values 

delete from A where a>=3 

-- insert two values into A and get the new primary keys 
MERGE a USING (SELECT a FROM A) AS B(a) 
ON (1 = 0) -- ignore the values, NOT MATCHED will always be true 
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES -- always insert here for this example 
OUTPUT $action, inserted.*, deleted.*, B.a; -- show the new primary key and source data 

R esult her satır için yeni bir birincil anahtar

INSERT, 3, NULL, 1 
INSERT, 4, NULL, 2 

yani (3, 4) ve eski bir (1, 2). Ör. #OUTPUT ve "INTO #OUTPUT;" ekleyerek OUTPUT yan tümcesinin sonunda kayıtları kaydeder.

+1

MERGE ifadesi benim en iyi arkadaşım :) – lambacck

+5

İyi bir açıklama ve örnek burada: http://sqlblog.com/blogs/jamie_thomson/archive/2010/01/06/ birleştirme-ve-çıktı-isviçre-ordu-bıçak-t-sql.aspx arasında –

İlgili konular