Tạo một bảng INTO VÀO với khóa chính


8

Có thể đối với cộng đồng này, vấn đề của tôi rất dễ, nhưng đối với tôi (một lập trình viên Java đơn giản) thì đó là một vấn đề LỚN.

Tôi có một DB lớn với ngày càng nhiều dữ liệu. Vì vậy, quản trị viên db bên ngoài đã tạo một công việc hiển thị cho tôi trong một bảng tạm thời dữ liệu mà tôi cần. Nhưng anh ta đã tạo bảng mà không có khóa chính và khi với dự án java của tôi đi đọc bảng này, tôi đã gặp lỗi.

Tôi không thể đọc bảng này vì khóa chính không tồn tại.

Tôi có thể chèn vào thủ tục khả năng tạo khóa chính tự động mà không thay đổi cấu trúc của thủ tục phức tạp này không?

Đây là sự khởi đầu của mã thủ tục được lưu trữ:

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 (...)

Cảm ơn trước

Câu trả lời:


5

Âm thanh như bạn đang tìm kiếm hàm IDENTITY () :

Chỉ được sử dụng trong câu lệnh CHỌN với mệnh đề bảng INTO để chèn cột nhận dạng vào bảng mới.

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 (...)

13
@Paola Mặc dù rõ ràng, điều này chỉ giải quyết phần tăng tự động của câu hỏi. Bảng vẫn không có khóa chính.
Martin Smith

9

Một số lựa chọn thay thế để thêm cột tăng tự động thông qua IDENTITY()chức năng như được đề xuất bởi @Shaneis là:

  1. Tạo bảng rõ ràng bằng cách sử dụng CREATE TABLEthay vì sử dụng SELECT INTO. Tôi rất thích phương pháp này vì nó cho phép bạn kiểm soát hoàn toàn Bảng đang được tạo, chẳng hạn như bao gồm cột tăng tự động chỉ định rằng đó là Khóa chính. Ví dụ:

    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}
    );
  2. Nếu bạn không thể thay đổi cách thức / thời gian / nơi bảng được tạo, bạn luôn có thể thêm Cột sau và khi làm như vậy, bạn được phép chỉ định cả hai đó là một IDENTITYcột có Khóa chính được tạo trên đó. Ví dụ:

    ALTER TABLE [dbo].[tmpTable]
      ADD [tmpTableID] INT NOT NULL
      IDENTITY(1, 1)
      PRIMARY KEY;

    Điều này thậm chí hoạt động nếu Bảng đã có dữ liệu trong đó: IDENTITYcột mới sẽ được điền như mong đợi, bắt đầu với giá trị được chỉ định cho seedtham số. Tuy nhiên, không có cách nào để kiểm soát thứ tự các giá trị được gán (đó là một trong nhiều lý do để đi với tùy chọn # 1, nếu có thể).

Ghi chú bổ sung:

  • Bạn có chắc chắn rằng bạn cần một Khóa chính và không chỉ đơn giản là một cột tự động tăng / duy nhất? Mặc dù thông thường nên có Khóa chính, nhưng nó không bắt buộc cũng không giống với cột tăng tự động. Tôi chỉ hỏi bởi vì cả tiêu đề và văn bản của câu hỏi này đều nói rằng bạn cần Khóa chính, nhưng bạn đang nói trong một nhận xét về Câu trả lời mà bạn chấp nhận rằng chỉ cần có cột tăng tự động hoạt động.

  • Bảng bạn đang sử dụng không thực sự là một bảng tạm thời. Các bảng tạm thời thực có tên bắt đầu bằng #hoặc ##cho các bảng tạm thời toàn cầu. Bảng bạn đang sử dụng dbo.tmpTablechỉ là một bảng thông thường, cố định có tiền tố là "tmp" để chỉ ra rằng nó có thể chỉ dành cho quá trình này và không phải là một phần của mô hình dữ liệu.

    Nếu mã ứng dụng không cần truy cập Bảng "tạm thời" này và tham chiếu duy nhất về nó nằm trong Quy trình được lưu trữ này, thì bạn có thể xem xét thay đổi nó thành Bảng tạm thời thực sự, có lợi thế là được dọn sạch khi quá trình hoàn tất, trong trường hợp đó bạn sẽ không cần DROP TABLEcâu lệnh.

  • Nếu bạn sẽ sử dụng Bảng vĩnh viễn thay vì Bảng tạm thời (trong trường hợp đó bạn cần tự dọn dẹp), thì DROP TABLEcâu lệnh phải có điều kiện, sao cho nó không bị lỗi nếu Bảng không tồn tại:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • Thay vì làm SELECT *, bạn nên chỉ định danh sách cột đầy đủ. Việc sử dụng *làm cho quá trình có nhiều khả năng bị phá vỡ khi bạn thêm cột / trường vào bảng hoặc truy vấn con (bất cứ điều gì aalà bí danh cho).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.