Create a "INTO" table with primary key
Some alternatives to adding the auto-increment column via the IDENTITY()
function as suggested by @Shaneis are:
Create the table explicitly using
CREATE TABLE
instead of usingSELECT INTO
. I much prefer this method as it gives you complete control over the Table that is being created, such as including the auto-increment column and specifying that it be the Primary Key. For example: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} );
If you can't change how / when / where the table is being created, you can always add a Column later, and when doing so, you are allowed to specify both that it be an
IDENTITY
column and have the Primary Key created on it. For example:ALTER TABLE [dbo].[tmpTable] ADD [tmpTableID] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY;
This even works if the Table already has data in it: the new
IDENTITY
column will be populated as expected, starting with the value specified for theseed
parameter. However, there is no way to control the order in which the values are assigned (which is one of several reasons to go with option #1, if at all possible).
Additional notes:
Are you sure that you need a Primary Key and not simply an auto-incrementing / unique column? While it is typically a good idea to have a Primary Key, it is neither required nor the same thing as an auto-incrementing column. I only ask because both the title and text of this Question state that you need a Primary Key, yet you are saying in a comment on the Answer that you accepted that simply having the auto-increment column worked.
The table you are using is not actually a temporary table. Real Temporary Tables have names starting with
#
, or##
for Global Temporary Tables. The table you are usingdbo.tmpTable
is just a regular, permanent table that is prefixed with "tmp" to indicate that it is probably just for this process and not part of the data model.If the app code doesn't need to access this "temporary" Table, and the only reference to it is within this Stored Procedure, then you might consider changing it to be a real Temporary Table, which has the advantage of being cleaned up when the process completes, in which case you wouldn't need the
DROP TABLE
statement.If you will be using a permanent Table instead of a Temporary Table (in which case you need to clean it up yourself), then the
DROP TABLE
statement should be conditional, such that it doesn't error if the Table doesn't exist:IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL) BEGIN DROP TABLE dbo.tmpTable; END;
Rather than doing
SELECT *
, you should specify the full column list. Using*
makes the process more likely to break when you add columns / fields to tables or subqueries (whateveraa
is an alias for).
Sounds like you are looking for the IDENTITY() function:
Is used only in a SELECT statement with an INTO table clause to insert an identity column into a new table.
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 (...)