Другие языки программирования и технологии

Вопрос знатокам MS SQL насчет хранимок - смотрите внутри.

Есть хранимка, содержащая запрос. Только запрос.
Как мне объяснили знающие люди, такие штуки используются, чтобы скрыть этот запрос (структуру базы и т. д.) от внешнего мира.
При вызове такая хранимка возвращает датасет и клиент может с ним работать. Тут все ясно.
А теперь внимание вопрос: что происходит, если такая хранимка вызывает еще одну такую же ПОСЛЕ запроса? Зачем это может быть сделано? Что вернется в этом случае?
Я понимаю, что можно это дело проверить при помощи натурных испытаний, проблема в том, что я их не могу провести - права никакие мне не дают, злые они, а кочегарить свой сервер несколько геморройно. Если кто-то может - я был бы очень благодарен.
Юра Кочанов
Юра Кочанов
57 721
вернётся две выборки.

зачем это нужно - вопрос сложный, поскольку внутри T-SQL это богатство полноценно использовать затруднительно. но внутри клиентского приложения - запросто.
ИС
Илья Сибилюк
84 002
Лучший ответ
Юра Кочанов Т. е. клиент получит массив из датасетов? Это не UNION какой-нибудь, просто 2 датасета?
Для неё есть индекс по data.
Запишем в неё миллион записей с монотонно убывающим значением data от 1000000 до 1.

Есть, допустим, хранимая процедура вида

create stored procedure RestrictA(@param1 int)
as
select * from A where data > @param1

теперь мы строим на её основе запрос типа "выбрать из её результатов все, где data меньше параметра 2". Как-то так:

create stored procedure RestrictA2(@param1 int, @param2 int)
as
exec RestrictA(@param1) into #temp
select * from temp where data < @param2

Попробуем вызвать её с простыми параметрами типа

exec RestrictA2(1, 0)

Что будет делать движок? Правильно, он сначала скопирует 999999 записей во временную таблицу, а потом выполнит по ней table scan. В итоге он вернёт 0 записей.

А что будет, если оформить RestrictA и RestrictA2 в виде table-valued function?
Правильно, движок подставит один запрос в другой, и выполнит запрос

select * from A where data < @param2 and data > @param1

Нетрудно видеть, что здесь будет выполнен ровно один index seek, и те же 0 записей будут возвращены гораздо быстрее.

Также нетрудно видеть, что сравнимую производительность для такого запроса вариант с хранимкой покажет только в том случае, если второй предикат отберёт ровно все записи, записанные в #temp.

очевидно, что вкладывание утяжелит выполнение. Но навряд ли усилит защиту.
Юра Кочанов Это прекрасно, но ни одна процедура не содержит параметров. Это просто 2 статических запроса. Зачем тогда о_О?