插入临时表,并创建一个 IDENTITY 字段,而不先声明临时表?
Posted
技术标签:
【中文标题】插入临时表,并创建一个 IDENTITY 字段,而不先声明临时表?【英文标题】:INSERT INTO a temp table, and have an IDENTITY field created, without first declaring the temp table? 【发布时间】:2008-09-23 20:13:37 【问题描述】:我需要选择一堆数据到一个临时表中,然后做一些二次计算;为了帮助它更有效地工作,我想在该表上有一个 IDENTITY 列。我知道我可以先用标识声明表,然后将其余数据插入其中,但是有没有办法一步完成?
【问题讨论】:
IDENTITY 列使多个用户的事情保持一致。 PRIMARY KEY 让事情变得高效。使用两者以获得最大效果。 【参考方案1】:哦,你们这些小信仰:
SELECT *, IDENTITY( int ) AS idcol
INTO #newtable
FROM oldtable
http://msdn.microsoft.com/en-us/library/aa933208(SQL.80).aspx
【讨论】:
当然,你不能有两个。只是不要选择 ident col 作为查询的一部分 如果使用 ORDER BY 子句并期望“idcol”的顺序相同,则需要小心。 support.microsoft.com/kb/273586 select cast (CurrentID as int) as CurrentID 如果 oldtable 有一个标识列,你应该喜欢这个【参考方案2】:您评论说:如果 oldtable 有标识列,则不起作用。
我想这就是你的答案。 #newtable 自动从旧表中获取标识列。运行下一条语句:
create table oldtable (id int not null identity(1,1), v varchar(10) )
select * into #newtable from oldtable
use tempdb
GO
sp_help #newtable
它显示#newtable 确实有标识列。
如果您不想要标识列,请在创建 #newtable 时尝试此操作:
select id + 1 - 1 as nid, v, IDENTITY( int ) as id into #newtable
from oldtable
【讨论】:
【参考方案3】:如果您想包含当前标识的列,您仍然可以这样做,但您必须明确列出列并将当前标识转换为 int(假设现在是一个),如下所示:
select cast (CurrentID as int) as CurrentID, SomeOtherField, identity(int) as TempID
into #temp
from myserver.dbo.mytable
【讨论】:
【参考方案4】:Good Question & Matt's 是一个很好的答案。如果旧表具有身份,则要稍微扩展语法,用户可以运行以下命令:
SELECT col1, col2, IDENTITY( int ) AS idcol
INTO #newtable
FROM oldtable
如果旧表的脚本是这样的:
CREATE TABLE [dbo].[oldtable]
(
[oldtableID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[col1] [nvarchar](50) NULL,
[col2] [numeric](18, 0) NULL,
)
【讨论】:
【参考方案5】:为了提高效率,您需要将其中一列声明为主键:
ALTER TABLE #mytable
ADD PRIMARY KEY(KeyColumn)
这不会为列名使用变量。
相信我,你最好做一个:CREATE #myTable TABLE
(或者可能是一个DECLARE TABLE @myTable
),它允许你直接设置IDENTITY
和PRIMARY KEY
。
【讨论】:
视情况而定;由于 B+ 树的维护,插入索引表(除了少数例外)比未索引表慢;此应用程序可能没有足够的数据加载到临时表中以使索引有价值。完全视情况而定,我们没有足够的信息了解 他想要一个“身份”来“让事情变得高效”。我们可以得出结论,他想通过一个不存在的 id 访问这些项目。很容易按不存在的 id 进行排序。 他没有定义高效——我的想法是他想要一个身份不是为了速度,而是为了易用性。但如果是性能问题,只需索引现有列之一【参考方案6】:如果在 * 之后,您为第二次中断查询的 id 列设置别名...并给它一个新名称...它神奇地开始工作。
select IDENTITY( int ) as TempID, *, SectionID as Fix2IDs
into #TempSections
from Files_Sections
【讨论】:
【参考方案7】:IIRC,INSERT INTO 命令使用源表的模式来创建临时表。这就是您不能只尝试创建带有附加列的表的部分原因。标识列在内部与称为生成器的 SQL Server 构造相关联。
【讨论】:
【参考方案8】:您可以执行 Select Into,它会根据您选择的字段动态创建表结构,但我认为它不会为您创建身份字段。
【讨论】:
以上是关于插入临时表,并创建一个 IDENTITY 字段,而不先声明临时表?的主要内容,如果未能解决你的问题,请参考以下文章