Sql-Server
使用主鍵創建一個“INTO”表
也許對於這個社區來說,我的問題很簡單,但對於我(一個簡單的 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 (...)
提前致謝
聽起來您正在尋找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 (...)
通過@Shaneis
IDENTITY()
建議的函式添加自動增量列的一些替代方法是:
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} );
- 如果您無法更改創建表的方式/時間/位置,您可以稍後添加一個列,這樣做時,您可以指定它是一個
IDENTITY
列並在其上創建主鍵。例如:ALTER TABLE [dbo].[tmpTable] ADD [tmpTableID] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY;
如果表中已經有數據,這甚至可以工作:新
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;
- 而不是這樣做
SELECT *
,您應該指定完整的列列表。當您將列/欄位添加到表或子查詢(無論是別名)時,使用*
使該過程更有可能中斷。aa