Sql-Server

使用主鍵創建一個“INTO”表

  • May 23, 2017

也許對於這個社區來說,我的問題很簡單,但對於我(一個簡單的 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 (...)

通過@ShaneisIDENTITY()建議的函式添加自動增量列的一些替代方法是:

  1. 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}
);
  1. 如果您無法更改創建表的方式/時間/位置,您可以稍後添加一個列,這樣做時,您可以指定它是一個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

引用自:https://dba.stackexchange.com/questions/139358