主キーを持つ「INTO」テーブルを作成する


8

たぶんこのコミュニティにとって私の問題は簡単ですが、私(単純なJavaプログラマー)にとってはそれは大きな問題です。

ますます多くのデータを含むBig DBがあります。したがって、外部データベース管理者は、一時テーブルに必要なデータを表示するジョブを作成しました。しかし、彼は主キーなしでテーブルを作成していました。私の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 (...)

前もって感謝します

回答:


5

あなたはIDENTITY()関数を探しているように聞こえます:

IDO列を新しいテーブルに挿入するために、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 (...)

14
@Paola明確にする必要がありますが、これは質問の自動インクリメント部分のみを扱います。テーブルにはまだ主キーがありません。
マーティン・スミス

9

@ShaneisでIDENTITY()提案されている関数を使用して自動インクリメント列を追加する代わりの方法は次のとおりです。

  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}
    );
  2. テーブルを作成する方法/時間/場所を変更できない場合は、いつでも列を追加できます。追加するときは、IDENTITYであることと、主キーを作成することの両方を指定できます。例えば:

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

    これは、テーブルにすでにデータが含まれている場合でも機能IDENTITYseedます。新しい列は、パラメーターに指定された値から期待どおりに入力されます。ただし、値が割り当てられる順序を制御する方法はありません(これは、可能な場合、オプション#1を使用するいくつかの理由の1つです)。

その他の注意事項:

  • 自動インクリメント/一意の列ではなく、主キーが必要ですか?通常、主キーを使用することをお勧めしますが、自動インクリメント列と同じである必要はありません。この質問のタイトルとテキストの両方に主キーが必要であると記載されているため、私は尋ねるだけですが、回答のコメントで、自動インクリメント列が機能していることを受け入れたと述べています。

  • 使用しているテーブルは、実際には一時テーブルではありません。リアルテンポラリーテーブルの名前は#、で始まるか##、グローバルテンポラリーテーブルの名前です。使用してdbo.tmpTableいるテーブルは、「tmp」というプレフィックスが付いた通常の永続的なテーブルであり、おそらくこのプロセス専用であり、データモデルの一部ではないことを示しています。

    アプリコードがこの「一時」テーブルにアクセスする必要がなく、それへの唯一の参照がこのストアドプロシージャ内にある場合は、それを実際の一時テーブルに変更することを検討できます。プロセスは完了しますDROP TABLE。その場合、ステートメントは必要ありません。

  • 一時テーブルの代わりに永続テーブルを使用する場合(この場合は自分でクリーンアップする必要があります)、DROP TABLEステートメントが条件付きであり、テーブルが存在しなくてもエラーにならないようにする必要があります。

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • ではなくSELECT *、完全な列リストを指定する必要があります。を使用*すると、テーブルまたはサブクエリ(aa別名)に列/フィールドを追加するときに、プロセスが中断する可能性が高くなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.