Возврат уникального идентификатора из вставленной записи

Я разрабатываю приложение C#, которое может переключаться между двумя базами данных - SQL-Server и локальной базой данных SQL-Compact.

При вставке чего-либо я хочу вернуть вставленный идентификатор, который является uniqueidentifier.

ExecuteScalar() не работает для uniqueidentifier. Только при использовании output inserted.id.

Но output inserted.id не поддерживается SQL-Compact.

Есть ли способ вернуть uniqueidentifier в обе базы данных?

Вы можете объявить уникальный идентификатор в своем коде как переменную, вставить его, а затем привести к varchar в своем выборе, чтобы вы могли использовать ExecuteScalar.

Sean Lange 23.01.2019 23:14

Или вы всегда можете сгенерировать новый guid на C#, так как это одно из преимуществ использования guids — их можно создавать в БД или приложении, поскольку они глобально уникальны.

Dale K 23.01.2019 23:22

Одной из основных особенностей GUID является то, что вы можете генерировать его из любого места. Это противоречит идентификаторам с автоинкрементом, которые могут генерироваться только базой данных. Поэтому я предлагаю вам использовать эту функцию и сгенерировать ваши GUID в вашем коде C#, тогда вам не нужно будет возиться с возвратом сгенерированных идентификаторов из базы данных. Честно говоря, когда я вижу код, который генерирует GUID в базе данных, я всегда удивляюсь, почему GUID использовался в первую очередь, потому что в этом случае целые числа с автоинкрементом работали бы лучше. Но есть редкие исключения.

Racil Hilan 23.01.2019 23:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
556
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

declare @GUID uniqueidentifier = newid()

insert (YourColumns)
values(@GUID)

select convert(varchar(36), @GUID) as MyKey

К сожалению, это не работает в SQL-Compact. Но я продолжаю пытаться

juergen d 23.01.2019 23:30

@juergend - см. комментарии под вашим вопросом о создании руководства в коде.

Dale K 23.01.2019 23:40

Только если другого выхода нет. Мне пришлось бы реорганизовать 10 тысяч строк кода.

juergen d 23.01.2019 23:41

Лучше всего использовать @@IDENTITY в сочетании с оператором select.

Передайте это как команду SQL:

  insert into myTable ( col1, col2, ...) values ( 'val1', 'val2', ...);SELECT @@IDENTITY;

По сути, это вставляет значение, а затем немедленно (в том же сеансе) вызывает самую последнюю созданную личность, которая будет той, которую вы только что вставили.

Затем в вашем коде: int iResult = (int)sqlCommand.ExecuteScalar()

И даже если бы это было так, SCOPE_IDENTITY было бы намного лучше.

Sean Lange 24.01.2019 15:17

Ах, я неправильно истолковал уникальный идентификатор как уникальный ключ/идентификацию.

IanCaz 24.01.2019 21:50

Только что понял, что это дубликат ответа @Sean Langem, я оставляю его, потому что он добавляет больше деталей, которые могут быть полезны для ОП.


Возможно, это не самое элегантное решение (создание GUID в приложении), однако я считаю, что оно должно решить вашу проблему. Обратите внимание, что я тестировал это только на SQL Server, а не на SQL Compact.

Используйте ExecuteScalar(), чтобы вернуть свой идентификатор, однако преобразуйте его в строку (varchar) в хранимой процедуре, а затем обратно в GUID в своем приложении.

Приведенный ниже пример является очень простым для демонстрационных целей, а код находится в VB.Net и не гарантирует закрытие соединения, обработку исключений и т. д.

Пример хранимой процедуры, возвращающей значение UNIQUEIDENTIFER в виде VARCHAR:

CREATE PROCEDURE test
AS 

    DECLARE @id uniqueidentifier
    SET @id = NEWID()

    SELECT CONVERT(VARCHAR(38), @id)
GO

Пример кода .Net для вызова базы данных и извлечения строки, а затем преобразования в guid.

Sub main()

    Dim id As Guid
    Dim stringId As String

    Using con As New SqlConnection("Server=<server>;Database=<DB>;Trusted_Connection=True;")
        Using cmd As New SqlCommand("test", con)
            cmd.CommandType = Data.CommandType.StoredProcedure

            con.Open()
            stringId = cmd.ExecuteScalar()
        End Using
    End Using

    id = New Guid(stringId)

End Sub
declare не поддерживается в SQL-Compact.
juergen d 24.01.2019 07:00
Ответ принят как подходящий

С SQL Server Compact сделать это невозможно.

Если вы должны использовать идентификаторы GUID, единственный способ — создать идентификатор GUID на клиенте, а не запрашивать сгенерированное значение у ядра базы данных.

Другие вопросы по теме