Я разрабатываю приложение C#, которое может переключаться между двумя базами данных - SQL-Server и локальной базой данных SQL-Compact.
При вставке чего-либо я хочу вернуть вставленный идентификатор, который является uniqueidentifier
.
ExecuteScalar()
не работает для uniqueidentifier
. Только при использовании output inserted.id
.
Но output inserted.id
не поддерживается SQL-Compact.
Есть ли способ вернуть uniqueidentifier
в обе базы данных?
Или вы всегда можете сгенерировать новый guid на C#, так как это одно из преимуществ использования guids — их можно создавать в БД или приложении, поскольку они глобально уникальны.
Одной из основных особенностей GUID
является то, что вы можете генерировать его из любого места. Это противоречит идентификаторам с автоинкрементом, которые могут генерироваться только базой данных. Поэтому я предлагаю вам использовать эту функцию и сгенерировать ваши GUID
в вашем коде C#, тогда вам не нужно будет возиться с возвратом сгенерированных идентификаторов из базы данных. Честно говоря, когда я вижу код, который генерирует GUID
в базе данных, я всегда удивляюсь, почему GUID
использовался в первую очередь, потому что в этом случае целые числа с автоинкрементом работали бы лучше. Но есть редкие исключения.
Вот как вы можете сделать это, используя переменную.
declare @GUID uniqueidentifier = newid()
insert (YourColumns)
values(@GUID)
select convert(varchar(36), @GUID) as MyKey
К сожалению, это не работает в SQL-Compact. Но я продолжаю пытаться
@juergend - см. комментарии под вашим вопросом о создании руководства в коде.
Только если другого выхода нет. Мне пришлось бы реорганизовать 10 тысяч строк кода.
Лучше всего использовать @@IDENTITY
в сочетании с оператором select.
Передайте это как команду SQL:
insert into myTable ( col1, col2, ...) values ( 'val1', 'val2', ...);SELECT @@IDENTITY;
По сути, это вставляет значение, а затем немедленно (в том же сеансе) вызывает самую последнюю созданную личность, которая будет той, которую вы только что вставили.
Затем в вашем коде:
int iResult = (int)sqlCommand.ExecuteScalar()
И даже если бы это было так, SCOPE_IDENTITY было бы намного лучше.
Ах, я неправильно истолковал уникальный идентификатор как уникальный ключ/идентификацию.
Только что понял, что это дубликат ответа @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.
С SQL Server Compact сделать это невозможно.
Если вы должны использовать идентификаторы GUID, единственный способ — создать идентификатор GUID на клиенте, а не запрашивать сгенерированное значение у ядра базы данных.
Вы можете объявить уникальный идентификатор в своем коде как переменную, вставить его, а затем привести к varchar в своем выборе, чтобы вы могли использовать ExecuteScalar.