Вам нужно использовать предложение «output», чтобы захватить «ключи» вставленных строк ....... сразу после их вставки.
Вот пример ... не точное совпадение .... но показывает эту идею.
http://granadacoder.wordpress.com/2008/12/10/sqlserver20052008-output-clause-in-insertupdatedelete-statements/
EDIT:
Вот пример того, что я сделал ....... где я ввожу "лицо" (материнской компании) и некоторые адреса электронной почты (дочернего объекта). Я измельчил xml, ваша таблица данных должна быть аналогичной.
Ключ в том, что я «ревизую» (с производным предложением) ИДЕНТИФИКАЦИЯ, сгенерированная с помощью Я вставляю Person ..... но я сохраняю эту информацию в соответствии с естественным уникальным идентификатором (SSN в этом примере). Когда я вставляю адреса электронной почты, у меня есть ИДЕНТИФИКАЦИЯ вставляемого Я.
Мои #TempTables будут «реальными столами» в вашем окончательном решении. My @VariableTable - это таблица «аудита», которая собирает и хранит информацию, собранную в разделе «выход».
IF OBJECT_ID('tempdb..#DestinationPersonParentTable') IS NOT NULL
begin
drop table #DestinationPersonParentTable
end
IF OBJECT_ID('tempdb..#DestinationEmailAddressPersonChildTable') IS NOT NULL
begin
drop table #DestinationEmailAddressPersonChildTable
end
CREATE TABLE #DestinationPersonParentTable
(
PersonParentSurrogateIdentityKey int not null identity (1001, 1),
SSNNaturalKey int,
HireDate datetime
)
declare @PersonOutputResultsAuditTable table
(
SSNNaturalKey int,
PersonParentSurrogateIdentityKeyAudit int
)
CREATE TABLE #DestinationEmailAddressPersonChildTable
(
DestinationChildSurrogateIdentityKey int not null identity (3001, 1),
PersonParentSurrogateIdentityKeyFK int,
EmailAddressValueNaturalKey varchar(64),
EmailAddressType int
)
-- Declare XML variable
DECLARE @data XML;
-- Element-centered XML
SET @data = N'
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Person>
<SSN>222222222</SSN>
<HireDate>2002-02-02</HireDate>
</Person>
<Person>
<SSN>333333333</SSN>
<HireDate>2003-03-03</HireDate>
</Person>
<EmailAddress>
<SSNLink>222222222</SSNLink>
<EmailAddressValue>[email protected]</EmailAddressValue>
<EmailAddressType>1</EmailAddressType>
</EmailAddress>
<EmailAddress>
<SSNLink>222222222</SSNLink>
<EmailAddressValue>[email protected]</EmailAddressValue>
<EmailAddressType>2</EmailAddressType>
</EmailAddress>
<EmailAddress>
<SSNLink>333333333</SSNLink>
<EmailAddressValue>[email protected]</EmailAddressValue>
<EmailAddressType>1</EmailAddressType>
</EmailAddress>
<EmailAddress>
<SSNLink>333333333</SSNLink>
<EmailAddressValue>[email protected]</EmailAddressValue>
<EmailAddressType>2</EmailAddressType>
</EmailAddress>
</root>
';
INSERT INTO #DestinationPersonParentTable (SSNNaturalKey , HireDate)
output inserted.SSNNaturalKey , inserted.PersonParentSurrogateIdentityKey into @PersonOutputResultsAuditTable (SSNNaturalKey , PersonParentSurrogateIdentityKeyAudit)
SELECT T.parentEntity.value('(SSN)[1]', 'INT') AS SSN,
T.parentEntity.value('(HireDate)[1]', 'datetime') AS HireDate
FROM @data.nodes('root/Person') AS T(parentEntity)
/* add a where not exists check on the natural key */
where not exists (
select null from #DestinationPersonParentTable innerRealTable where innerRealTable.SSNNaturalKey = T.parentEntity.value('(SSN)[1]', 'INT'))
;
/* Optional. You could do a UPDATE here based on matching the #DestinationPersonParentTableSSNNaturalKey = T.parentEntity.value('(SSN)[1]', 'INT')
You could Combine INSERT and UPDATE using the MERGE function on 2008 or later.
*/
select 'PersonOutputResultsAuditTable_Results' as Label, * from @PersonOutputResultsAuditTable
INSERT INTO #DestinationEmailAddressPersonChildTable ( PersonParentSurrogateIdentityKeyFK , EmailAddressValueNaturalKey , EmailAddressType)
SELECT par.PersonParentSurrogateIdentityKeyAudit ,
T.childEntity.value('(EmailAddressValue)[1]', 'varchar(64)') AS EmailAddressValue,
T.childEntity.value('(EmailAddressType)[1]', 'INT') AS EmailAddressType
FROM @data.nodes('root/EmailAddress') AS T(childEntity)
/* The next join is the "trick". Join on the natural key (SSN)....**BUT** insert the PersonParentSurrogateIdentityKey into the table */
join @PersonOutputResultsAuditTable par on par.SSNNaturalKey = T.childEntity.value('(SSNLink)[1]', 'INT')
where not exists (
select null from #DestinationEmailAddressPersonChildTable innerRealTable where innerRealTable.PersonParentSurrogateIdentityKeyFK = par.PersonParentSurrogateIdentityKeyAudit AND innerRealTable.EmailAddressValueNaturalKey = T.childEntity.value('(EmailAddressValue)[1]', 'varchar(64)'))
;
print '/#DestinationPersonParentTable/'
select * from #DestinationPersonParentTable
print '/#DestinationEmailAddressPersonChildTable/'
select * from #DestinationEmailAddressPersonChildTable
select SSNNaturalKey , HireDate , '---' as Sep1 , EmailAddressValueNaturalKey , EmailAddressType , '---' as Sep2, par.PersonParentSurrogateIdentityKey as ParentPK , child.PersonParentSurrogateIdentityKeyFK as childFK from #DestinationPersonParentTable par join #DestinationEmailAddressPersonChildTable child
on par.PersonParentSurrogateIdentityKey = child.PersonParentSurrogateIdentityKeyFK
IF OBJECT_ID('tempdb..#DestinationPersonParentTable') IS NOT NULL
begin
drop table #DestinationPersonParentTable
end
IF OBJECT_ID('tempdb..#DestinationEmailAddressPersonChildTable') IS NOT NULL
begin
drop table #DestinationEmailAddressPersonChildTable
end
Является Sql Server 2012? И почему тег C#? Даже если вы контролируете это с помощью кода C#, ваш вопрос вообще не связан с этим. – gunr2171
Хотя логика с настройками обычно предпочтительнее, есть время и места для использования курсора, и это может быть одно. Курсоры иногда могут быть более удобочитаемыми и удобными для чтения. Если вам нужно всего лишь предпринять действия на нескольких строках, вы можете сделать курсор для выбора только тех конкретных строк исходной таблицы, которые объединены с вашими несколькими целевыми таблицами. Или, если вам нужно, вы можете отступить к простым старым заявлениям IF. – criticalfix
@criticalfix, я должен подчеркнуть: курсоры очень медленны, когда дело доходит до большого набора данных. Выбирайте свои ситуации внимательно. – gunr2171