#sql #sql-server #view #procedure
#sql #sql-сервер #Вид #процедура
Вопрос:
У меня есть пользовательский просмотр, давайте назовем его [MIKE].Table
, который выполняет фильтрованный выбор SELECT * FROM TABLE WHERE TL_FILTERKEY in (1,2,3)
Итак, если Mike подключается к серверу и выполняет
"SELECT * FROM TABLE"
он увидит только часть данных из таблицы.
Существует также процедура с правами dbo и разрешением Mike для выполнения как
CREATE PROCEDURE tbSelect
as
SELECT * FROM TABLE
Если Майк выполнит exec tbSelect
, он увидит ВСЕ строки из таблицы, но не отфильтрованные.
Как написать процедуру так, чтобы она выбирала данные из пользовательского представления (отфильтрованные строки)?
Я попытался воссоздать процедуру ‘С ВЫПОЛНЕНИЕМ ОТ ИМЕНИ ‘Mike» и ‘С ВЫПОЛНЕНИЕМ ОТ ИМЕНИ ВЫЗЫВАЮЩЕГО’, однако возвращаются все строки.
Ответ №1:
Ваш вопрос немного сбивает с толку, и вы не упоминаете свою версию SQL Server, но я подозреваю, что ваша проблема связана с схемами. Когда вы ссылаетесь на объект без схемы, SQL Server сначала ищет объект в схеме пользователя по умолчанию, а затем в схеме dbo.
Как полное предположение, я думаю, у вас есть пользователь по имени Mike, у которого по умолчанию также есть схема Mike
, вызываемое представление Mike.Table
и вызываемая таблица dbo.Table
. Когда Майк запускает свой запрос, он Table
разрешается в Mike.Table
, но когда db_owner запрашивает, Table
он разрешается как dbo.Table
.
Чтобы избежать путаницы, вам, вероятно, следует использовать более четкие имена объектов (по крайней мере, для тестирования) и всегда указывать имяобъектов с указанием владельца:
create table dbo.TestTable (col1 int)
go
insert into dbo.TestTable
select 1
union all
select 2
union all
select 3
go
-- this will return all rows
select col1 from dbo.TestTable
go
create view dbo.TestView
as
select col1
from dbo.TestTable
where col1 >= 2
go
-- this will return 2 rows
select col1 from dbo.TestView
go
create procedure dbo.TestProc
as
select col1 from dbo.TestView
go
-- this will also return 2 rows
exec dbo.TestProc
go
drop proc dbo.TestProc
go
drop View dbo.TestView
go
drop table dbo.TestTable
go
Комментарии:
1. Да, мы можем получить данные из представления как [schemas].ViewName внутри процедуры. Идея заключалась в том, чтобы использовать трюк с выбором данных без схем. Может быть, это возможно, выполнив это через системные таблицы. Проблема решена путем создания таблицы сопоставления: [пользователь] -> [просмотр].