21 ответов:
@@IDENTITYне является безопасной областью и вернет вам идентификатор из другой таблицы если у вас есть триггер вставки в исходной таблице, всегда используйтеSCOPE_IDENTITY()
Это, как я сделать мой хранимых процедур для MSSQL с ID автоматически.
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();
Если вы используете PHP и MySQL, вы можете использовать функцию mysql_insert_id (), которая сообщит вам идентификатор элемента, который вы только что установили.
Но без вашего языка и СУБД я просто снимаю в темноте здесь.
Это очень хорошо работает в 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 вставляет несколько строк.
опять нет языкового агностического ответа, но в 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(); }
Если вы работаете с Oracle:
вставка в таблицу (поля....) значения (значений...) Возврат (список полей...) в переменные...)
пример:
вставить в PERSON (NAME) значения ('JACK') возвращая ID_PERSON в vIdPerson
или если вы звоните... Java с CallableStatement (sry, это мое поле)
ВСТАВИТЬ В PERSON (NAME) ЗНАЧЕНИЯ ('JACK') ВОЗВРАТ ID_PERSON INTO ?
и объявление параметра autput для оператора
нет стандартного способа сделать это (так же, как нет стандартного способа создать автоматически увеличивающиеся идентификаторы). Вот два способа сделать это в PostgreSQL. Предположим, что это ваша таблица:
CREATE TABLE mytable ( id SERIAL PRIMARY KEY, lastname VARCHAR NOT NULL, firstname VARCHAR );вы можете сделать это в двух операторах, пока они являются последовательными операторами в одном и том же соединении (это будет безопасно в PHP с пулом соединений, потому что PHP не возвращает соединение обратно в пул, пока ваш скрипт сделано):
INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George'); SELECT lastval();lastval() дает вам последнее автоматически сгенерированное значение последовательности, используемое в текущем соединении.
другой способ-использовать PostgreSQL возвращение положения о вставить о себе:
INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;эта форма возвращает результирующий набор, как выберите заявление, а также удобно для возврата любого вида расчетного значения по умолчанию.
важно отметить, что использование запросов поставщика SQL для получения последнего вставленного идентификатора безопасно использовать, не опасаясь параллельных подключений.
Я всегда думал, что вам нужно создать транзакцию, чтобы вставить строку, а затем выбрать последний вставленный идентификатор, чтобы избежать извлечения идентификатора, вставленного другим клиентом.
но эти запросы конкретного поставщика всегда извлекают последний вставленный идентификатор для текущего подключения к база данных. Это означает, что последний вставленный идентификатор не может быть затронут другими вставками клиента, пока они используют свое собственное соединение с базой данных.
из сайта я узнал следующие вещи:
SQL-сервер – функция @@Identity против функция scope_identity() против функция ident_current – получить последней вставленной личность запись 25 марта 2007 года по pinaldave
ВЫБЕРИТЕ @ @ IDENTITY Он возвращает последнее значение идентификатора, полученное в соединении, независимо от таблицы, которая произвела значение, и независимо от области действия оператора, который произвел значение. @Функция @ @ Identity возвращает последнее значение идентификатора, введенного в таблицу в текущем сеансе. Хотя @ @ IDENTITY ограничен текущим сеансом, он не ограничен текущей областью действия. Если у вас есть триггер в таблице, который вызывает создание идентификатора в другой таблице, вы получите идентификатор, который был создан последним, даже если это был триггер, который его создал.
ВЫБЕРИТЕ ФУНКЦИИ SCOPE_IDENTITY() Он возвращает последнее значение идентификатора, созданное в соединении и оператором в той же области, независимо от таблицы, которая произвела значение. SCOPE_IDENTITY (), как и @@IDENTITY, вернет последнее значение identity, созданное в текущем сеансе, но также ограничит его вашей текущей областью. Другими словами, он возвращает последнее значение идентификатора, которое вы явно создали, а не любое удостоверение, созданное триггером или пользовательской функцией.
выберите IDENT_CURRENT ('tablename’) Он возвращает последнее значение идентификатора, полученное в таблице, независимо от соединения, которое создало значение, и независимо от области действия оператора, который произвел значение. IDENT_CURRENT не ограничивается областью действия и сеансом; он ограничен указанной таблицей. Функция ident_current возвращает значение идентификатора, созданное для указанной таблицы в любом сеансе и области.
для 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.
помните, что @@IDENTITY возвращает последний созданный идентификатор для вашего текущего соединения, а не обязательно идентификатор для недавно добавленной строки в таблице. Вы всегда должны использовать SCOPE_IDENTITY() для возврата идентификатора недавно добавленной строки.
какую базу данных вы используете? Насколько мне известно, для этого нет агностического метода базы данных.
вот как я сделал это с помощью параметризованных команд.
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();
sql = "INSERT INTO MyTable (Name) VALUES (@Name);" + "SELECT CAST(scope_identity() AS int)"; SqlCommand cmd = new SqlCommand(sql, conn); int newId = (int)cmd.ExecuteScalar();
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
ответ Роба был бы самым продавцом-агностиком, но если вы используете MySQL более безопасным и правильным выбором будет встроенный .
SELECT @@Scope_Identity as Idесть также @ @ identity, но если у вас есть триггер, он вернет результаты чего-то, что произошло во время триггера, где scope_identity уважает вашу область.
- вставить строку с известным идентификатором GUID.
- извлеките autoId-поле с этим guid.
это должно работать с любой базой данных.
Решение 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
в TransactSQL для этого можно использовать предложение OUTPUT.
INSERT INTO my_table(col1,col2,col3) OUTPUT INSERTED.id VALUES('col1Value','col2Value','col3Value')
простой ответ:
command.ExecuteScalar()по умолчанию возвращает первый столбец
Возвращаемое Значение система типов.Объект Первый столбец первой строки в результирующем наборе, или пустая ссылка (nothing в Visual Basic), если результирующий набор пуст. Возвращает максимум 2033 символов.
скопировал из MSDN
Comments