我想使用
将标识列添加到目前没有ID列的表中Alter Table Names
Add Id_new Int Identity(1, 1)
编辑:我的问题似乎导致了一些混乱,所以我试着澄清:
我们从客户那里得到了几千张表进行分析。他们中的大多数没有和ID列。
我们从客户端加载表,但不知道里面是什么。
为了进一步分析,我们想要添加自己的ID列。
可能会发生,编辑过的表可能会被意外删除。 发生这种情况时,我们需要能够重新加载数据,再次添加ID列,ID列必须与我们第一次加载数据时的顺序完全相同。 否则,如果我们在下游分析中引用ID,我们将引用与之前不同的行。
那么:是不是这样,添加到表中的ID号始终是相同的顺序,因为表中的数据是相同的?
备注:我和同事一起讨论了我们可以在所有列上使用order by子句的可能性。这将创造我们想要的东西。但是,我们有数千个表,所以这将是一个非常痛苦。数据是我们要为客户端分析的转储。所以问题是,如果有一种更容易,可重现的方法来添加和ID到所有表中的所有行。
答案 0 :(得分:1)
问题是为什么要重新添加Add Id_new Int Identity(1, 1)
?
未订购表格。该命令无法保证重复。
如果您希望重复,您的数据需要提供自己的PK。
如果您先创建身份,然后插入身份将在插入顺序中,但它可能有间隙。
如果所有行都产生了唯一的排序,那么这应该有效
select col1, col2, col3
, row_number() over (order by col1, col2, col3) as rn
from table;
如果要重新加载表,则可以截断。
答案 1 :(得分:1)
IDENTITY
为特定表生成递增数字。您无法确保添加到不同表中的行将获得相同的数字。无论如何,这不是IDENTITY的目的。
SQL Server可以为这种情况生成sequence numbers。您可以使用SEQUENCE来生成可在多个表中使用的递增数字,甚至可以确保表中的唯一数字。
如何使用序列取决于您插入数据的方式。最简单的方法是获取一个新值并使用它在多个表中插入行:
SET @myID = NEXT VALUE FOR Test.CountBy1 ;
INSERT INTO Table1 (ID,....) VALUES(@myID,....);
但是在批量导入方案中这并不是很有帮助。
另一种选择是使用sp_sequence_get_range存储过程保留整个数字范围。您可以要求例如10个号码,该功能将返回起始号码,并确保不会为其他任何人生成接下来的10个号码:
DECLARE @range_first_value sql_variant ,
@range_first_value_output sql_variant ;
EXEC sp_sequence_get_range
@sequence_name = N'RangeSeq'
, @range_size = 10
, @range_first_value = @range_first_value_output OUTPUT ;
SELECT @range_first_value_output AS FirstNumber ;
这可以在ETL脚本或代码中使用,以生成递增的数字并将它们分配给行。
在表格中生成唯一数字要容易得多。只需使用NEXT VALUE FOR ...
作为ID列的默认值
答案 2 :(得分:0)
这是一项复杂的任务,可以通过多种方式解决。我将尝试解释如何解决它。
第1步: 为所有表生成脚本:how do i generate scripts for all tables with single stroke in sql server 2000
第2步:
将Identity列添加到所有表。为此,我们需要编辑在第1步中生成的脚本,并将) ON [PRIMARY]
的所有实例替换为, IdCol int IDENTITY(1,1)) ON [PRIMARY]
第3步:
我们需要更改表名,使其与原始名称不同。将所有].[
替换为].[temp1234_
第4步:
运行脚本。这将创建所有表的空副本,并将IdCol
作为标识列。
第5步:
为所有表生成INSERT
脚本。运行以下查询:
select 'INSERT INTO ['+name+'] SELECT * from ['+REPLACE(name, 'temp1234_', '')+'] order by column_name'
from sys.all_objects where name like 'temp1234_%'
这将为您提供每个表的INSERT
脚本的行列表。将column_name
替换为可用作order by子句的列的名称。如果列的名称因表而异,则必须为每个表指定正确的列名称。
第6步: 复制所有行,运行,等待完成,检查结果。
正如其他人已经说过的那样 - 无法控制Identity为每一行分配的值,因此要控制您需要将数据重新插入到新表中。
IF 您的表已经拥有了您希望用作标识的列,而无需重新分配值,可能有办法执行此操作。如果是这样,请告诉我。