我希望能够将具有标识列的表中的数据插入SQL Server 2005中的临时表中。
TSQL看起来像:
-- 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中,有没有一种方法可以将临时表中的列的identity属性删除而无需显式列出的所有列?我特别想使用“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
请注意错误消息“当使用列列表并且IDENTITY_INSERT为ON时,只能在中指定表'#TmpMyTable'中标识列的显式值”。 -我特别不想使用如上所述的列列表。
更新2
尝试过the suggestion from 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's solution工作,但是它建议了以下可行的解决方案:以非身份列为前缀并删除身份列:
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的建议只在临时表中存储键也是一个不错的建议,尽管在这种特定情况下,由于某些原因,我更倾向于将所有列都存储在临时表中。
最佳答案
如果您只是按照您的描述来处理行,那么最好仅在临时表中选择前N个主键值,例如:
CREATE TABLE #KeysToProcess
(
TempID int not null primary key identity(1,1)
,YourKey1 int not null
,YourKey2 int not null
)
INSERT INTO #KeysToProcess (YourKey1,YourKey2)
SELECT TOP n YourKey1,YourKey2 FROM MyTable
键不应该经常更改(我希望如此),但是其他列可以这样做不会有任何危害。
得到插入的@@ ROWCOUNT,您可以在TempID上做一个简单的循环,其中从1到@@ ROWCOUNT
和/或
只需将#KeysToProcess加入您的MyKeys表即可,无需重复所有数据。
,这在我的SQL Server 2005上运行良好,其中MyTable.MyKey是一个标识列。
-- Create empty temp table
SELECT *
INTO #TmpMikeMike
FROM (SELECT
m1.*
FROM MyTable m1
LEFT OUTER JOIN MyTable m2 ON m1.MyKey=m2.MyKey
WHERE 1=0
) dt
INSERT INTO #TmpMike
SELECT TOP 1 * FROM MyTable
SELECT * from #TmpMike
编辑
这项工作,没有任何错误...
-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM (SELECT
m1.*
FROM MyTable m1
LEFT OUTER JOIN MyTable m2 ON m1.KeyValue=m2.KeyValue
WHERE 1=0
) dt
...
WHILE ...
BEGIN
...
INSERT INTO #Tmp_MyTable
SELECT TOP (@n) *
FROM MyTable
...
END
,但是,您真正的问题是什么? 为什么在将“*”插入此临时表时需要循环?您也许可以改变策略并总体上提出更好的算法。
关于sql - 如何在SQL Server 2005中删除列的IDENTITY属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/713960/