我想要在SQL Server 2005中将带有标识列的表中的数据插入到临时表中。
对应的T-SQL代码如下:
-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM MyTable
WHERE 1=0
...
WHILE ...
BEGIN
...
INSERT INTO #Tmp_MyTable
SELECT TOP (@n) *
FROM MyTable
...
END
上面的代码创建了一个带有标识列的#Tmp_Table,然后插入操作失败并显示错误信息:“只有在使用列列表且 IDENTITY_INSERT 为 ON 时,才能为表 '#Tmp_MyTable' 中的标识列指定显式值。”在TSQL中是否有一种方法可以在不显式列出所有列的情况下删除临时表中列的标识属性?我想要明确地使用“SELECT *”,这样如果将来添加了新列到MyTable,代码仍将继续工作。
我认为删除和重新创建列会改变其位置,从而无法使用SELECT *。
更新:我尝试按照一个回答中提供的方法使用IDENTITY_INSERT,但它没有起作用-请参见下面的示例。我做错了什么?
-- Create test table
CREATE TABLE [dbo].[TestTable](
[ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
)
GO
-- Insert some data
INSERT INTO TestTable
(Name)
SELECT 'One'
UNION ALL
SELECT 'Two'
UNION ALL
SELECT 'Three'
GO
-- Create empty temp table
SELECT *
INTO #Tmp
FROM TestTable
WHERE 1=0
SET IDENTITY_INSERT #Tmp ON -- I also tried OFF / ON
INSERT INTO #Tmp
SELECT TOP 1 * FROM TestTable
SET IDENTITY_INSERT #Tmp OFF
GO
-- Drop test table
DROP TABLE [dbo].[TestTable]
GO
请注意错误信息"An explicit value for the identity column in table '#TmpMyTable' can only be specified when a column list is used and IDENTITY_INSERT is ON." - 如上所述,我不想使用列列表。
更新2: 尝试了Mike的建议,但出现了相同的错误:
-- Create empty temp table
SELECT *
INTO #Tmp
FROM (SELECT
m1.*
FROM TestTable m1
LEFT OUTER JOIN TestTable m2 ON m1.ID=m2.ID
WHERE 1=0
) dt
INSERT INTO #Tmp
SELECT TOP 1 * FROM TestTable
我想这么做的原因是:MyTable是一个暂存表,其中可能包含大量要合并到另一个表中的行。我想循环处理来自暂存表的行,在每个事务中处理N行,将它们插入/更新到我的主表中,并从暂存表中删除它们。我意识到还有其他实现方法。
更新3
我无法使Mike的解决方案工作,但它提出了以下解决方案,该解决方案可以工作:在非标识列前缀并删除标识列:
SELECT CAST(1 AS NUMERIC(18,0)) AS ID2, *
INTO #Tmp
FROM TestTable
WHERE 1=0
ALTER TABLE #Tmp DROP COLUMN ID
INSERT INTO #Tmp
SELECT TOP 1 * FROM TestTable
在这种情况下,为临时表仅存储键的Mike建议也是一个好建议,尽管有些原因我更喜欢将所有列都存储在临时表中。