Создать таблицу «INTO» с первичным ключом

8

Может быть, для этого сообщества моя проблема проста, но для меня (простого программиста на 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 (...)

заранее спасибо

PaolaG
источник

Ответы:

5

Похоже, вы ищете функцию IDENTITY () :

Используется только в операторе SELECT с предложением таблицы INTO для вставки столбца идентификаторов в новую таблицу.

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
источник
14
@Paola Хотя, чтобы быть ясным, это касается только части вопроса с автоинкрементом. В таблице все еще нет первичного ключа.
Мартин Смит
9

Некоторые альтернативы добавлению столбца автоинкремента с помощью IDENTITY()функции, предложенной @Shaneis :

  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, если это вообще возможно).

Дополнительные замечания:

  • Вы уверены, что вам нужен первичный ключ, а не просто автоинкрементный / уникальный столбец? Хотя обычно желательно иметь первичный ключ, он не является ни обязательным, ни тем же, что и автоинкрементный столбец. Я спрашиваю только потому, что и заголовок, и текст этого Вопроса указывают на то, что вам нужен Первичный ключ, но в комментарии к ответу вы говорите, что приняли простой столбец автоинкремента.

  • Таблица, которую вы используете, на самом деле не является временной таблицей. Реальные временные таблицы имеют имена, начинающиеся с #или ##для глобальных временных таблиц. Используемая вами таблица dbo.tmpTable- это обычная постоянная таблица с префиксом «tmp», указывающая, что она, вероятно, предназначена только для этого процесса и не является частью модели данных.

    Если коду приложения не требуется доступ к этой «временной» таблице, и единственная ссылка на него находится внутри этой хранимой процедуры, то вы можете рассмотреть возможность ее изменения на настоящую временную таблицу, которая имеет преимущество в том, что ее очищают, когда процесс завершается, и в этом случае вам не нужно DROP TABLEутверждение.

  • Если вы будете использовать постоянную таблицу вместо временной таблицы (в этом случае вам нужно будет очистить ее самостоятельно), то DROP TABLEоператор должен быть условным, чтобы он не выдавал ошибку, если таблица не существует:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • Вместо того, чтобы делать SELECT *, вы должны указать полный список столбцов. Использование *повышает вероятность прерывания процесса при добавлении столбцов / полей к таблицам или подзапросам (для aaкоторых используется псевдоним).

Соломон Руцкий
источник