Не удалось вставить запись из хранимой процедуры, вызванной из веб-службы

#sql-server-2008 #stored-procedures

#sql-server-2008 #хранимые процедуры

Вопрос:

У меня есть следующая таблица:

 CREATE TABLE [dbo].[omgbbq](
    [tbl_key] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](10) NOT NULL,
    [id] [int] NULL,
 CONSTRAINT [PK_omgbbq] PRIMARY KEY CLUSTERED 
(
    [tbl_key] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
  

… и следующая хранимая процедура:

 CREATE PROCEDURE sp_omgwth 
    @name VARCHAR(10), 
    @id INT
AS
BEGIN
    INSERT INTO omgbbq (name, id) VALUES (@name, @id);
    SELECT MAX(tbl_key) AS Max_tbl_key FROM omgbbq;
END
  

Я добавил одну запись, вызвав процедуру из SSMS:

 EXEC sp_omgwth 'Gareth', 2
  

и получаем

 tbl_key,name,id
1,Gareth,2
  

Пока все хорошо. Коллега пытается вызвать его из веб-службы и получает возврат
‘Max_tbl_key’ 2

Также, как и ожидалось. Однако запись не отображается в таблице. Когда я добавляю новую запись, вызывая SP из SSMS, мы видим следующее в таблице:

 tbl_key,name,id
1,Gareth,2
3,Gawain,4
  

Похоже, что он добавил запись, которая увеличила значение идентификатора, но затем…Я не знаю, откатил его или что-то в этом роде.

Есть идеи? Мы оба подключаемся к серверу как один и тот же пользователь, поэтому не похоже, что это может быть проблема с правами доступа. Мы получаем такое же поведение из другой таблицы и другого SP, поэтому мы создали эти два в качестве тестов.

Комментарии:

1. Вы НИКОГДА не должны использовать SELECT MAX(tbl_key) ... для получения значения IDENTITY столбца — используйте SELECT SCOPE_IDENTITY()... вместо этого! Намного безопаснее — не сломается в ситуациях параллелизма!

2. Вероятно, я должен уточнить, что разработчики проследили проблему, насколько могли. Они обнаружили, что передаваемый оператор SQL отлично работал при копировании и вставке в SSMS. Кроме того, использование той же базы кода для добавления записи с помощью инструкции INSERT также работало. Кажется, что-то странное конкретно в том, что веб-служба вызывает любую хранимую процедуру с помощью INSERT .

3. Согласен с marc's комментарием выше. Вы не должны использовать MAX . Пожалуйста, опубликуйте код вашей веб-службы. Это в транзакции, которая никогда не фиксируется, звучит правдоподобно.

Ответ №1:

Лучший способ выяснить, что происходит в базе данных, — запустить трассировку. Запустите профилировщик SQL Server и вызовите веб-службу для хранимой процедуры. Затем посмотрите на события, чтобы узнать, что происходит.

Это загадочная проблема, но просмотр трассировки покажет вам, что и почему.

Комментарии:

1. Хорошая мысль. Трассировка показывает, что на самом деле это было внутри транзакции, которая была откатана: USE [tha_db] go BEGIN TRAN go exec sp_omgwtf 'matt', '2' go ROLLBACK TRAN go BEGIN TRAN go

2. Разработчики посмотрят, где их код мог бы это сделать завтра. Спасибо за все идеи и указания!

Ответ №2:

Возможно, вам нужно предоставить пример вызова клиента SQL из кода веб-службы. Вы можете попробовать установить и проверить статус возврата ВЫПОЛНЕНИЯ.

Комментарии:

1. В вызове client нет ничего особенного, у меня нет к нему доступа, но я мог бы получить его, если это действительно необходимо. Я думаю, что важным моментом является то, что call отлично работает, вызывая любую хранимую процедуру, в которой НЕТ INSERT .

2. Кроме того, не могли бы вы уточнить, что вы подразумеваете под «установкой и проверкой статуса возврата ВЫПОЛНЕНИЯ»?