2010-10-12 2 views
10

Я проверил документацию для SCOPE_IDENTITY() и в нем говорится: «Сфера - это модуль: хранимая процедура, триггер, функция или пакет». Это просто, когда я запускаю запрос в SSMSE, но в C# я использую SqlCommand для выполнения моих операторов.SCOPE_IDENTITY в C# - диапазон

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

ответ

7

Предлагаю подумать о том, что ваши команды C# и T-SQL «партии» полностью отделены друг от друга.

Подумайте только о том, что SQLCommand является только вашей оболочкой выполнения, в которой фактическое определение того, что представляет собой пакет, определяется и контролируется языком T-SQL.

Область вашей сессии поддерживается на уровне объектов Connection.

Скорее всего, вы найдете следующее сообщение для форума MSDN. Обратите внимание, как в первом примере выполняются две отдельные команды SQL, но SCOPE_IDENITY() второго вызова может видеть результат предыдущего вызова. Это связано с тем, что текущая область видимости отображается на уровне соединения.

SQLCommand With Parameters and Scope_Indentity

Для полноты объяснения, почему это не работает, используя параметры, как позднее показано в связанном, например, потому, что sp_executesql выполняется в пределах своей собственной сферы и поэтому, следовательно, не может видеть сферу действия подключение.

[EDIT]

Дальнейшее чтение для более пытливого читателя, пожалуйста, найти VB.NET код ниже приведен пример выполнения двух отдельных команд на одном соединении, причем вторая команда успешно выдачи SCOPE_IDENTITY().

Исходный код может быть выполнен из компонента SCRIPT пакета задач SSIS. Вам также нужно будет отредактировать детали подключения для вашей среды, а также создать объект таблицы, на который делается ссылка.

Сценарий создания таблицы:

create table TestTable 
(
    ID int identity(1,1) primary key not null, 
    SomeNumericData int not null 
); 

VB.NET Источник Листинг:

Imports System 
Imports System.Data 
Imports System.Math 
Imports Microsoft.SqlServer.Dts.Runtime 
Imports System.Data.SqlClient.SqlConnection 
Imports Windows.Forms.MessageBox 

Public Class ScriptMain 



    Public Sub Main() 
     ' 
     ' Add your code here 

     Dim oCnn As New Data.SqlClient.SqlConnection 
     Dim sSQL As String 
     Dim sSQL2 As String 
     Dim resultOne As Integer 
     Dim resultTwo As Integer 
     Dim messageBox As Windows.Forms.MessageBox 

     resultOne = 0 
     resultTwo = 0 

     oCnn.ConnectionString = "Server=ServerName;Database=DatabaseName;Trusted_Connection=true" 
     sSQL = "INSERT INTO TestTable(SomeNumericData) VALUES(666) " 
     sSQL2 = "SELECT SCOPE_IDENTITY()" 
     Dim oCmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL, oCnn) 
     Dim oCmd2 As SqlClient.SqlCommand = New SqlClient.SqlCommand(sSQL2, oCnn) 

     oCmd.CommandType = CommandType.Text 
     oCmd.Connection = oCnn 
     oCnn.Open() 

     resultOne = oCmd.ExecuteNonQuery() 
     resultTwo = Convert.ToInt32(oCmd2.ExecuteScalar()) 

     oCnn.Close() 

     messageBox.Show("result1:" + resultOne.ToString + Environment.NewLine + "result2: " + resultTwo.ToString) 

     Dts.TaskResult = Dts.Results.Success 
    End Sub 
End Class 
+0

«это потому, что область поддерживается/видима на уровне соединения». я не согласен с вами .. область определяется тем, где вы указываете scope_identity() в своем запросе, в связанном примере 1, в 2 запросах выполняются разные команды. так как оба находятся в разных областях, он возвращает null ... Таким образом, область действия - только для каждой команды .. не соединение ... – RameshVel

+0

@Ramesh Vel: найдите исходное сообщение, чтобы включить исходный код, который проверяет видимость видимости сеанса на две отдельные команды в соединении. –

+0

Я выполнил почти такой же тест, но в C# и выполнении SCOPE_IDENTITY() в отдельных командах хорошо работает, хотя я вставлял еще несколько записей в таблицу между вызовом для вставки и выбирал scope_identity() (консольное приложение , ReadLine() между командами) – kubal5003

1

Я считаю, что сфера применима только для одной команды, а не для всего соединения.

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT SCOPE_IDENTITY()" 
SQLCommand.CommandText = strSQL 
Id = SQLCommand.ExecuteScalar() 

В приведенном выше коде strSQL полный размах, и он всегда возвращает значение идентификатора @@ ассоциированного вставки заявления.

поэтому последующие команды будут иметь свой собственный объем.

+0

Я склонен не согласиться с тобой. –

+0

@john, почему это так ?? – RameshVel

+0

@Ramesh Vel: Следующий пример кода, как представляется, предлагает иначе: http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/080280b7-9c2d-4ee5-afe0-5c07d2affc7c –

Смежные вопросы