SQL: Как получить идентификатор значений, которые я просто вставлял?

Я вставил некоторые значения в таблицу. Существует столбец, значение которого автогенерируется. В следующем выражении моего кода я хочу получить это значение.

Можете ли вы рассказать мне, как это сделать правильно?

Ответ 1

@@IDENTITY не является безопасным для области и вернет вам идентификатор из другой таблицы, если у вас есть триггер insert в исходной таблице, всегда используйте SCOPE_IDENTITY()

Ответ 2

Вот как я делаю свои процедуры хранения для MSSQL с автогенерированным идентификатором.

CREATE PROCEDURE [dbo].[InsertProducts]
    @id             INT             = NULL OUT,
    @name           VARCHAR(150)    = NULL,
    @desc           VARCHAR(250)    = NULL

AS

    INSERT INTO dbo.Products
       (Name,
        Description)
    VALUES
       (@name,
        @desc)

    SET @id = SCOPE_IDENTITY();

Ответ 3

Если вы используете PHP и MySQL, вы можете использовать функцию mysql_insert_id(), которая сообщит вам идентификатор элемента, который вы только что внесли.
Но без вашего языка и СУБД я просто снимаю в темноте.

Ответ 4

Это очень хорошо работает в SQL 2005:

DECLARE @inserted_ids TABLE ([id] INT);

INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6])
OUTPUT INSERTED.[id] INTO @inserted_ids
VALUES (@col1,@col2,@col3,@col4,@col5,@col6)

Это дает возможность вернуть все идентификаторы, если оператор INSERT вставляет несколько строк.

Ответ 5

Опять не агностический ответ языка, но в Java он выглядит следующим образом:

Connection conn = Database.getCurrent().getConnection();  
PreparedStatement ps =  conn.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);
try {  
    ps.executeUpdate();  
    ResultSet rs = ps.getGeneratedKeys();  
    rs.next();  
    long primaryKey = rs.getLong(1);  
} finally {  
    ps.close();  
}  

Ответ 6

Если вы работаете с Oracle:

Вставка в таблицу (поля...) значения (значения...) ВОЗВРАЩЕНИЕ (список полей...) INTO (переменные...)

Пример:

ВСТАВЬТЕ ЧЕЛОВЕК (НАЗВАНИЕ) ЗНАЧЕНИЯ ( "ДЖЕК" ) ВОЗВРАЩЕНИЕ ID_PERSON INTO vIdPerson

или если вы звоните с... Java с помощью CallableStatement (sry, it my field)

ВСТАВИТЬ В ЧЕЛОВЕК (НАЗВАНИЕ) ЗНАЧЕНИЯ ( "ДЖЕК" ) ВОЗВРАЩЕНИЕ ID_PERSON INTO?

и объявление параметра autput для оператора

Ответ 7

Нет стандартного способа сделать это (так же, как нет стандартного способа создания автоинкрементных идентификаторов). Вот два способа сделать это в PostgreSQL. Предположим, что это ваша таблица:

CREATE TABLE mytable (
  id SERIAL PRIMARY KEY,
  lastname VARCHAR NOT NULL,
  firstname VARCHAR
);

Вы можете сделать это в двух операциях, если они являются последовательными операторами в одном соединении (это будет безопасно в PHP с пулом соединений, поскольку PHP не возвращает соединение в пул до тех пор, пока ваш script не будет сделано):

INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George');
SELECT lastval();

lastval() дает вам последнее автоматически генерируемое значение последовательности, используемое в текущем соединении.

Другим способом является использование предложения PostgreSQL RETURNING в INSERT:

INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;

Эта форма возвращает результирующий набор точно так же, как оператор SELECT, а также удобна для возврата любого расчетного значения по умолчанию.

Ответ 8

Важно отметить, что использование SQL-запросов поставщика для извлечения последнего вставленного идентификатора безопасно использовать, не опасаясь о параллельных подключениях.

Я всегда думал, что вам нужно создать транзакцию, чтобы вставить строку, а затем ВЫБРАТЬ последний вставленный идентификатор, чтобы избежать получения идентификатора, вставленного другим клиентом.

Но эти специфические запросы поставщика всегда извлекают последний вставленный идентификатор для текущего подключения к базе данных. Это означает, что последние вставленные идентификаторы не могут быть затронуты другими вставками клиента, если они используют собственное соединение с базой данных.

Ответ 9

С сайта я узнал о следующих вещах:

SQL SERVER - @@IDENTITY vs SCOPE_IDENTITY() против IDENT_CURRENT - Получить последнюю вставленную идентификационную запись 25 марта 2007 г. pinaldave

SELECT @@IDENTITY Он возвращает последнее значение IDENTITY, созданное в соединении, независимо от таблицы, которая произвела значение, и независимо от области действия оператора, который произвел значение. @@IDENTITY вернет последнее значение идентификатора, введенное в таблицу текущего сеанса. Хотя @@IDENTITY ограничен текущим сеансом, он не ограничивается текущей областью. Если у вас есть триггер в таблице, который заставляет создать личность в другой таблице, вы получите идентификатор, который был создан последним, даже если это был триггер, который его создал.

SELECT SCOPE_IDENTITY() Он возвращает последнее значение IDENTITY, созданное в соединении, и оператором в той же области действия, независимо от таблицы, которая произвела значение. SCOPE_IDENTITY(), например @@IDENTITY, вернет последнее значение идентификации, созданное в текущем сеансе, но оно также ограничит его и вашей текущей областью. Другими словами, он вернет последнее значение идентификатора, которое вы явно создали, а не любое удостоверение, созданное триггером или пользовательской функцией.

SELECT IDENT_CURRENT ('tablename) Он возвращает последнее значение IDENTITY, созданное в таблице, независимо от соединения, которое создало значение, и независимо от области действия оператора, который произвел значение. IDENT_CURRENT не ограничивается областью и сеансом; он ограничен указанной таблицей. IDENT_CURRENT возвращает значение идентификатора, сгенерированное для конкретной таблицы, в любом сеансе и в любой области.

Ответ 10

Для SQL 2005:

Предполагая следующее определение таблицы:

CREATE TABLE [dbo].[Test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [somevalue] [nchar](10) NULL,
) 

Вы можете использовать следующее:

INSERT INTO Test(somevalue)
OUTPUT INSERTED.ID
VALUES('asdfasdf')

Будет возвращено значение столбца ID.

Ответ 11

Помните, что @@IDENTITY возвращает недавно созданный идентификатор для вашего текущего соединения, а не обязательно идентификатор недавно добавленной строки в таблице. Вы всегда должны использовать SCOPE_IDENTITY(), чтобы вернуть личность недавно добавленной строки.

Ответ 12

Какую базу данных вы используете? Насколько мне известно, для этого не существует агностического метода базы данных.

Ответ 13

Вот как я это сделал, используя параметризованные команды.

MSSQL

 INSERT INTO MyTable (Field1, Field2) VALUES (@Value1, @Value2); 
 SELECT SCOPE_IDENTITY(); 

MySQL

 INSERT INTO MyTable (Field1, Field2) VALUES (?Value1, ?Value2);
 SELECT LAST_INSERT_ID();

Ответ 14

sql = "INSERT INTO MyTable (Name) VALUES (@Name);" +
      "SELECT CAST(scope_identity() AS int)";
SqlCommand cmd = new SqlCommand(sql, conn);
int newId = (int)cmd.ExecuteScalar();

Ответ 15

Ms SQL Server: это хорошее решение, даже если вы вставляете больше строк:

 Declare @tblInsertedId table (Id int not null)

 INSERT INTO Test ([Title], [Text])
 OUTPUT inserted.Id INTO @tblInsertedId (Id)
 SELECT [Title], [Text] FROM AnotherTable

 select Id from @tblInsertedId 

Ответ 16

Ответ Rob будет самым агронизирующим агентом, но если вы используете MySQL, более безопасный и правильный выбор будет встроенной функцией LAST_INSERT_ID().

Ответ 17

SELECT @@Scope_Identity as Id

Существует также идентификатор @@, но если у вас есть триггер, он вернет результаты того, что произошло во время запуска, где scope_identity уважает вашу область.

Ответ 18

  • введите строку с известным указателем.
  • введите поле autoId с этим директором.

Это должно работать с любой базой данных.

Ответ 19

Решение Oracle на базе среды разработки:

CREATE OR REPLACE PACKAGE LAST
AS
ID NUMBER;
FUNCTION IDENT RETURN NUMBER;
END;
/

CREATE OR REPLACE PACKAGE BODY LAST
AS
FUNCTION IDENT RETURN NUMBER IS
    BEGIN
    RETURN ID;
    END;
END;
/


CREATE TABLE Test (
       TestID            INTEGER ,
    Field1      int,
    Field2      int
)


CREATE SEQUENCE Test_seq
/
CREATE OR REPLACE TRIGGER Test_itrig
BEFORE INSERT ON Test
FOR EACH ROW
DECLARE
seq_val number;
BEGIN
IF :new.TestID IS NULL THEN
    SELECT Test_seq.nextval INTO seq_val FROM DUAL;
    :new.TestID := seq_val;
    Last.ID := seq_val;
END IF;
END;
/

To get next identity value:
SELECT LAST.IDENT FROM DUAL

Ответ 20

В TransactSQL вы можете использовать предложение OUTPUT для достижения этого.

INSERT INTO my_table(col1,col2,col3) OUTPUT INSERTED.id VALUES('col1Value','col2Value','col3Value')

FRI: http://msdn.microsoft.com/en-us/library/ms177564.aspx

Ответ 21

Самый простой ответ:

command.ExecuteScalar()

по умолчанию возвращает первый столбец

Возвращаемое значение Тип: System.Object Первый столбец первой строки в результирующем наборе или нулевая ссылка (Nothing в Visual Basic), если набор результатов пуст. Возвращает максимум 2033 символа.

Скопировано из MSDN