插入临时表,并创建一个 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),它允许你直接设置IDENTITYPRIMARY 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 字段,而不先声明临时表?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 存储过程创建临时表并插入值

在存储过程创建临时表,插入字段,更新字段

mysql创建临时表,将查询结果插入已有表中

ORACLE存储过程创建临时表并插入数据。

mysql创建临时表,将查询结果插入已有的表

SQL临时表使用