Pao*_*laG 8 sql-server stored-procedures auto-increment identity
也许对这个社区来说,我的问题很简单,但对我(一个简单的 Java 程序员)来说,这是一个大问题。
我有一个包含越来越多数据的大数据库。因此,外部数据库管理员创建了一个作业,在临时表中向我显示我需要的数据。但是他创建了没有主键的表,当我的 java 项目去读取这个表时,我得到一个错误。
我无法读取此表,因为主键不存在。
我可以在程序中插入创建自动增量主键的可能性,而不改变这个复杂程序的结构吗?
这是存储过程代码的开头:
USE [MYDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[spSchedula_Scadenzario]
as
begin
drop table MYDB.dbo.tmpTable
select
aa.*
into MYDB.dbo.tmpTable
from (...)
Run Code Online (Sandbox Code Playgroud)
提前致谢
IDENTITY()
通过@Shaneis建议的函数添加自动增量列的一些替代方法是:
使用CREATE TABLE
而不是使用显式创建表SELECT INTO
。我更喜欢这种方法,因为它可以让您完全控制正在创建的表,例如包括自动增量列并指定它为主键。例如:
CREATE TABLE dbo.tmpTable
(
tmpTableID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
...
{all columns represented by aa.* in the sample query in the Question}
);
Run Code Online (Sandbox Code Playgroud)如果您无法更改创建表的方式/时间/位置,您始终可以稍后添加一个列,并且在这样做时,您可以指定它是一个IDENTITY
列并在其上创建主键。例如:
ALTER TABLE [dbo].[tmpTable]
ADD [tmpTableID] INT NOT NULL
IDENTITY(1, 1)
PRIMARY KEY;
Run Code Online (Sandbox Code Playgroud)
如果表中已经有数据,这甚至有效:新IDENTITY
列将按预期填充,从为seed
参数指定的值开始。但是,无法控制分配值的顺序(如果可能的话,这是使用选项 #1 的几个原因之一)。
补充说明:
您确定需要主键而不是简单的自动递增/唯一列吗?虽然拥有主键通常是一个好主意,但它既不是必需的,也与自动递增列相同。我之所以这么问是因为这个问题的标题和文本都表明您需要一个主键,但是您在对答案的评论中说您接受了只需让自动增量列工作即可。
您使用的表实际上不是临时表。Real Temporary Tables 的名称以#
, 或##
Global Temporary Tables开头。您正在使用的表dbo.tmpTable
只是一个以“tmp”为前缀的常规永久表,以表明它可能仅用于此过程,而不是数据模型的一部分。
如果应用程序代码不需要访问这个“临时”表,并且对它的唯一引用是在这个存储过程中,那么你可以考虑把它改成一个真正的临时表,它的优点是在该过程完成,在这种情况下,您将不需要该DROP TABLE
语句。
如果您将使用永久表而不是临时表(在这种情况下您需要自己清理它),那么该DROP TABLE
语句应该是有条件的,这样如果表不存在就不会出错:
IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
BEGIN
DROP TABLE dbo.tmpTable;
END;
Run Code Online (Sandbox Code Playgroud)SELECT *
您应该指定完整的列列表,而不是执行。*
当您向表或子查询(无论aa
是什么别名)添加列/字段时,使用会使过程更容易中断。
听起来您正在寻找IDENTITY()函数:
仅在带有 INTO 表子句的 SELECT 语句中用于将标识列插入到新表中。
USE [MYDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[spSchedula_Scadenzario]
as
begin
drop table MYDB.dbo.tmpTable
select
-- Create new identity here.
NewPrimaryKey = IDENTITY(int, 1, 1),
aa.*
into MYDB.dbo.tmpTable
from (...)
Run Code Online (Sandbox Code Playgroud)