#sql-server-2005 #stored-procedures #permissions #temp-tables
Вопрос:
Я вошел в базу данных SQL Server 2005 как пользователь, не являющийся пользователем sa, «bhk», который является участником только роли «общедоступного» сервера. Следующий код пытается выполнить в хранимой процедуре, вызванной пользователем «bhk». Эта строка кода…
TRUNCATE TABLE #Table1
DBCC CHECKIDENT('#Table1', RESEED, @SequenceNumber) WITH NO_INFOMSGS
вызывает эту ошибку…
Пользователь «гость» не имеет разрешения на запуск DBCC CHECKIDENT для объекта
«#Table1__00000000007F».
Я знаю о разрешениях, необходимых для запуска DBCC CHECKIDENT…
Вызывающий должен владеть таблицей или быть членом фиксированной роли сервера sysadmin, фиксированной роли базы данных db_owner или фиксированной роли базы данных db_ddladmin.
Поэтому у меня есть два вопроса:
- Поскольку » bhk «вызывает хранимую процедуру, которая создает временную таблицу, не должен ли» bhk » быть владельцем и иметь право запускать DBCC CHECKIDENT?
- Почему сообщение об ошибке возвращает, что у пользователя «гость» нет разрешения? Насколько мне известно, я не вошел в систему как «гость».
Любая помощь будет очень признательна.
Ответ №1:
Вот альтернативное решение, которое может сработать, если вам нужно повторно ввести порядковый номер более 1.
TRUNCATE #Table1
SET IDENTITY_INSERT #Table1 ON
INSERT INTO #Table1 (TableID) -- This is your primary key field
VALUES (@SequenceNumber - 1)
SET IDENTITY_INSERT #Table1 OFF
DELETE FROM #Table1
Это делается для того, чтобы установить IDENTITY_INSERT в вашей временной таблице, чтобы вы могли добавить строку с явным идентификатором. Затем вы можете удалить эту строку, но дальнейшие вставки должны начинаться с последнего порядкового номера.
Ответ №2:
Ты написал:
«Вызывающий должен владеть таблицей или быть членом фиксированной роли сервера sysadmin, фиксированной роли db_owner».
Итак (если это не ошибка), согласно безупречной логике лейтенанта Коломбо, каждое из предположений должно быть ложным. Это означает, что вызывающий абонент не владеет таблицей, даже если он ее создал.
На самом деле, похоже, что все объекты, созданные в tempd, по умолчанию принадлежат dbo. Вы можете изучить его, если выполните следующие действия в анализаторе запросов:
- Подключитесь к своей базе данных с помощью пользователя с низкими разрешениями.
- Выполнять:
CREATE TABLE #NotMyTable (TestID int identity)
- Подключитесь к базе данных tempdb того же SQL-сервера, что и dbo
- Выполнять:
SELECT user_name(uid) FROM sysobjects WHERE name LIKE '#NotMyTable%'
Вы увидите, что dbo является владельцем временной таблицы.
Итак, что может быть решением?
(Предисловие: Мне не нравятся такого рода манипуляции, но интеллектуальный стимул движет мной… 😉 )
Таким образом, вы могли бы написать другую хранимую процедуру, которая обновляет UID в sysobjects базы данных tempdb до значения вашего пользователя (дрожь!). Я тестировал его только в анализаторе запросов. После обновления я мог бы выполнить вашу команду DBCC CHECKIDENT.
Комментарии:
1. Хотя это, вероятно, сработало бы, я согласен с тем, что мне не нравятся такого рода манипуляции.
2. Какое замечательное замечание. Он сияет благодаря своему остроумию.
Ответ №3:
Вы можете сделать это, полностью уточнив таблицу tempdb.
DBCC CHECKIDENT([tempdb..#Table1], RESEED, @SequenceNumber) WITH NO_INFOMSGS
Комментарии:
1. Я все еще получаю проблемы с разрешениями, даже когда полностью квалифицируюсь.
Ответ №4:
Альтернативным решением для выполнения команд TRUNCATE и CHECKIDENT было бы просто удалить и заново создать вашу временную таблицу. Например.
DROP TABLE #Table1
CREATE TABLE #Table1
(
....
)
Однако это может быть не самым эффективным решением.
Комментарии:
1. Вы правы. Однако в моей ситуации цель состоит в том, чтобы сбросить столбец идентификаторов до значения, отличного от 1. Удаление/Создание приведет только к сбросу столбца до 1 и, похоже, не позволяет использовать переменные в качестве значения для параметра НАЧАЛЬНОГО значения ИДЕНТИФИКАТОРА.
Ответ №5:
Я только что столкнулся с этим. Ответ, к которому я пришел, состоял в том, чтобы предоставить соответствующей учетной записи разрешения в базе данных tempdb, где, очевидно, были созданы эти таблицы.
Комментарии:
1. Я решил эту проблему, войдя в систему как sa и проверив логин, который я использовал, чтобы убедиться, что в базе данных tempdb отображен пользователь, который был членом ddladmin