#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. Кроме того, не могли бы вы уточнить, что вы подразумеваете под «установкой и проверкой статуса возврата ВЫПОЛНЕНИЯ»?