web-dev-qa-db-ja.com

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

たぶんこのコミュニティにとって私の問題は簡単ですが、私にとっては(単純な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 (...)

前もって感謝します

8
PaolaG

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

@ 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;
    

    これは、テーブルにすでにデータが含まれている場合でも機能します。新しいIDENTITY列は、seedパラメータに指定された値から始まり、期待どおりに入力されます。ただし、値が割り当てられる順序を制御する方法はありません(これは、可能な場合、オプション#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のエイリアス)に追加したときに、プロセスが中断する可能性が高くなります。

9
Solomon Rutzky