У меня есть хранимая процедура, которую я выполняю из VB.NET. SP должен вставлять записи в таблицу и возвращать набор вызывающему приложению. Возвращенный набор - это записи, которые были вставлены.Исключение из хранимой процедуры не попало в .NET с использованием SqlDataAdapter.Fill (DataTable)
Если ошибка INSERT
не удалась, исключение поймано и повторно выбрано в SP, но я никогда не вижу исключения в своем приложении. Уровень серьезности равен 14, поэтому я должен это увидеть.
Вот хранимая процедура:
BEGIN TRY
BEGIN TRANSACTION
-- Declare local variables
DECLARE @DefaultCategoryID AS BIGINT = 1 -- 1 = 'Default Category' (which means no category)
DECLARE @DefaultWeight AS DECIMAL(18,6) = 0
DECLARE @InsertionDate AS DATETIME2(7) = GETDATE()
DECLARE @SendToWebsite AS BIT = 0 -- 0 = 'NO'
DECLARE @MagentoPartTypeID AS BIGINT = 1 -- For now, this is the only part type we are importing from COPICS ('simple' part type)
DECLARE @NotUploaded_PartStatusID AS TINYINT = 0 -- 0 = 'Not Uploaded'
DECLARE @Enabled_PartStatusID AS TINYINT = 1 -- 1 = 'Enabled'
DECLARE @Disabled_PartStatusID AS TINYINT = 2 -- 2 = 'Disabled'
-- Get the part numbers that will be inserted (this set will be returned to calling procedure).
SELECT c.PartNumber
FROM
COPICSPartFile c
LEFT JOIN Part p on c.PartNumber = p.PartNumber
WHERE
p.PartNumber IS NULL
-- Insert new records from COPICSPartFile (records that don't exist - by PartNumber - in Part table)
INSERT INTO Part
([PartNumber]
,[ReplacementPartNumber]
,[ShortDescription]
,[ListPrice]
,[PartStatusTypeID]
,[Weight]
,[CategoryID]
,[DateInserted]
,[SendToWebsite]
,[FileName]
,[MagentoPartTypeID]
,[PrintNumber])
SELECT
c.PartNumber
,c.ReplacementPartNumber
,c.ShortDescription
,c.ListPrice
,CASE WHEN c.PartStatusTypeID = @Enabled_PartStatusID THEN @NotUploaded_PartStatusID ELSE @Disabled_PartStatusID END
,@DefaultWeight
,@DefaultCategoryID
,@InsertionDate
,@SendToWebsite
,@FileName
,@MagentoPartTypeID
,c.PrintNumber
FROM
COPICSPartFile c
LEFT JOIN Part p on c.PartNumber = p.PartNumber
WHERE
p.PartNumber IS NULL
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
THROW;
END CATCH
А вот код .net:
Try
'Create command
Dim command As New SqlCommand
command.CommandType = CommandType.StoredProcedure
conn = New SqlConnection(m_ConnectionString)
command.Connection = conn
command.CommandText = "trxInsertPartFromCOPICSPartFile"
With command.Parameters
.AddWithValue("@FileName", fileName)
End With
Dim da As New SqlDataAdapter(command)
Dim dt As New DataTable
da.Fill(dt)
If dt.Rows.Count > 0 Then
Return dt
Else
Return Nothing
End If
Catch ex As SqlException
Dim myMessage As String = ex.Message
Finally
If conn.State <> ConnectionState.Closed Then
conn.Close()
End If
End Try
Как я пытался выяснить, почему исключение (клавиша дублирует) не является пойманный в моем приложении, я попытался прокомментировать заявление SELECT
в SP перед INSERT
и вуалой. Исключение из INSERT
попадает в приложение.
Может кто-нибудь объяснить мне, почему заявление SELECT
вызывает это? Я знаю, что могу разбить SELECT
на другой SP, но я хотел бы оставить все это одной атомной транзакцией, если это возможно. Это ожидаемое поведение? Есть ли способ обойти это?
Спасибо.
Когда вы говорите, не видя исключение в приложении вы имеете в виду в пользовательском интерфейсе или войти? Или вы говорите, что точка останова не попадает? На самом деле вы ничего не делаете с исключением. Вы отбрасываете его. – TyCobb
@TyCobb - Я устанавливаю точку останова там, и это не ударит, когда я отлаживаю. Первоначально я позволял исключению пузыряться до другого метода и обрабатывать его там. Просто добавлена уловка для упрощения отладки. – TrailJon
Вероятно, это «съедено» методом «Fill». Как насчет создания SqlDataReader, выполняющего 'command.ExecuteReader()' и используя считыватель для заполнения 'DataTable' через' Load() '? Таким образом, ошибка должна возникать в 'ExecuteReader()' и должна быть увлекательной. ** ИЛИ ** возможно, это уже не 'SqlException', выходящий из' Fill', так что просто поймайте общий «Исключение». –