Buat tabel "INTO" dengan kunci utama

8

Mungkin untuk komunitas ini masalah saya mudah, tetapi bagi saya (seorang programmer Java sederhana) itu adalah masalah BESAR.

Saya memiliki DB Besar dengan lebih banyak data. Jadi, admin db eksternal telah membuat pekerjaan yang menunjukkan kepada saya di tabel sementara data yang saya butuhkan. Tetapi dia telah membuat tabel tanpa kunci primer dan ketika dengan proyek java saya pergi untuk membaca tabel ini, saya mendapatkan kesalahan.

Saya tidak bisa membaca tabel ini karena kunci utama tidak ada.

Dapatkah saya memasukkan dalam prosedur kemungkinan untuk membuat kunci primer autoincremental tanpa mengubah struktur prosedur yang rumit ini?

Ini adalah awal dari kode prosedur yang tersimpan:

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

Terima kasih sebelumnya

PaolaG
sumber

Jawaban:

5

Sepertinya Anda mencari fungsi IDENTITY () :

Digunakan hanya dalam pernyataan SELECT dengan klausa tabel INTO untuk menyisipkan kolom identitas ke dalam tabel baru.

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
sumber
14
@ Paola Meskipun harus jelas ini hanya membahas bagian kenaikan otomatis dari pertanyaan. Tabel masih tidak memiliki kunci utama.
Martin Smith
9

Beberapa alternatif untuk menambahkan kolom kenaikan otomatis melalui IDENTITY()fungsi seperti yang disarankan oleh @Shaneis adalah:

  1. Buat tabel secara eksplisit menggunakan CREATE TABLEalih-alih menggunakan SELECT INTO. Saya lebih suka metode ini karena memberi Anda kontrol penuh atas Tabel yang sedang dibuat, seperti termasuk kolom kenaikan otomatis dan menetapkan bahwa itu adalah Kunci Utama. Sebagai contoh:

    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. Jika Anda tidak dapat mengubah cara / kapan / di mana tabel dibuat, Anda selalu dapat menambahkan Kolom nanti, dan saat melakukannya, Anda diperbolehkan menentukan keduanya bahwa itu adalah IDENTITYkolom dan memiliki Kunci Utama yang dibuat di atasnya. Sebagai contoh:

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

    Ini bahkan berfungsi jika Tabel sudah memiliki data di dalamnya: IDENTITYkolom baru akan diisi seperti yang diharapkan, dimulai dengan nilai yang ditentukan untuk seedparameter. Namun, tidak ada cara untuk mengontrol urutan penetapan nilai (yang merupakan salah satu dari beberapa alasan untuk memilih opsi # 1, jika memungkinkan).

Catatan tambahan:

  • Apakah Anda yakin bahwa Anda memerlukan Kunci Utama dan bukan hanya kolom penambahan-otomatis / unik? Meskipun biasanya merupakan ide yang baik untuk memiliki Kunci Utama, itu tidak diperlukan atau hal yang sama dengan kolom penambahan otomatis. Saya hanya bertanya karena judul dan teks Pertanyaan ini menyatakan bahwa Anda memerlukan Kunci Utama, namun Anda mengatakan dalam komentar pada Jawaban bahwa Anda menerima bahwa hanya dengan membuat kolom kenaikan otomatis berfungsi.

  • Tabel yang Anda gunakan sebenarnya bukan tabel sementara. Real Temporary Tables memiliki nama yang dimulai dengan #, atau ##untuk Global Temporary Tables. Tabel yang Anda gunakan dbo.tmpTablehanyalah tabel biasa, permanen yang diawali dengan "tmp" untuk menunjukkan bahwa itu mungkin hanya untuk proses ini dan bukan bagian dari model data.

    Jika kode aplikasi tidak perlu mengakses Tabel "sementara" ini, dan satu-satunya referensi untuk itu berada dalam Prosedur Tersimpan ini, maka Anda dapat mempertimbangkan mengubahnya menjadi Tabel Sementara yang nyata, yang memiliki keuntungan dibersihkan ketika proses selesai, dalam hal ini Anda tidak perlu DROP TABLEpernyataan itu.

  • Jika Anda akan menggunakan Tabel permanen alih-alih Tabel Sementara (dalam hal ini Anda perlu membersihkannya sendiri), maka DROP TABLEpernyataan tersebut harus bersyarat, sehingga tidak kesalahan jika Tabel tidak ada:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • Daripada melakukan SELECT *, Anda harus menentukan daftar kolom lengkap. Menggunakan *membuat proses lebih cenderung rusak ketika Anda menambahkan kolom / bidang ke tabel atau subqueries (apa pun aaalias untuk).

Solomon Rutzky
sumber