这可能是之前提出并回答的问题,但我自己找不到,但我遇到了以下问题。
我有一个名为“成本”的标识列的表 我还有一张叫做InvoiceCosts的桌子
成本是'基础'表格中包含金额,时间戳等等。
InvoiceCosts是继承的'表格中包含对发票和其他发票仅相关列的引用。
现在在存储过程中生成成本时,我在SQL 2005中做了什么(我们已经切换到SQL 2012)是以下代码(当我编写它时我不喜欢但它有效)< / p>
--add temp id column
print 'add temp_id'
alter table Costs add temp_id int
--Create temp table
print 'create #InvoiceCosts'
create table #InvoiceCosts (Costs_ID int, Invoice_ID int)
print 'insert record'
INSERT INTO Costs
([SomeField1]
,[SomeField2]
,[SomeField3]
,temp_id)
output
inserted.id,
inserted.temp_id
into
#InvoiceCosts
select
'Dummy Data',
'Dummy Data',
'Dummy Data'
,Invoice_ID
FROM
Invoices
--Insert into InvoiceCosts
print 'insert into InvoiceCosts'
insert into InvoiceCosts
select Costs_ID, Invoice_ID from #Debiteur_Kosten_Faktuur
--Drop temp table
print 'truncate #Debiteur_Kosten_Faktuur'
truncate table #Debiteur_Kosten_Faktuur
print 'drop #InvoiceCosts'
drop table #InvoiceCosts
现在,我已经简化了代码以消除混乱,但想法是InvoiceCosts表有一个FK引用需要填写的Costs表。我不能为我的生活找到一种方法来做到这一点,而没有那个可怕的临时表......
目前这个代码不再用作Storedprocedure,当被调用来执行temp_id列不存在的问题时(尽管SP本身应该在需要它之前添加列线...)我可以通过添加来解决这个问题它,执行SP(然后我得到一个关于列名称必须是唯一的错误),再次删除列然后运行到SP将使其工作....然而这种工作显然是迟钝的我和我做一些SQL Server并不觉得这样做的事情我觉得这样做不舒服(我认为无论如何)
我已经研究了CTE(http://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx),我认为这可以做到这一点,但我还没有设法让它至少工作。
另外需要注意的是,这会同时插入多个记录,因此使用SCOPE_IDENTITY或其他类似记录也是不可能的。
任何人都知道如何巧妙地做到这一点(不改变表的结构)?
答案 0 :(得分:1)
此处的问题是,在创建存储过程时,SQL Server会尝试检查对象的名称。如果表格不存在,那就没问题;它被称为延迟名称解析。但是,如果表存在,但表中的一个或多个列不存在,则会引发错误。您在程序中添加列的事实没有区别,因为它是同一批次。
查看here了解详情。
解决方法是预先添加列,或者使用动态SQL来访问新添加的列。
至于你要解决的实际问题,为什么你需要一个#temp表,你不能直接使用output
插入InvoiceCosts表吗?也许我不明白,因为我没有看到整个DDL。我的意思是这样的:
INSERT INTO Costs
([SomeField1]
,[SomeField2]
,[SomeField3]
)
output
inserted.id,
Invoice_ID
into
InvoiceCosts
select
'Dummy Data',
'Dummy Data',
'Dummy Data'
,Invoice_ID
FROM
Invoices