Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вернуть SELECT и OUTPUT параметр  [new]
relief
Member

Откуда:
Сообщений: 1197
Есть процедура которая принимает OUTPUT параметр.
Процедура возвращает Селект с множеством столбцов.
OUTPUT параметр - должен вернуть общее кол-во записей попавшее под Селект
Как без создания временных таблиц вернуть Селект и установить значение для OUTPUT параметра?

Проблема в том, что резульат селекта может быть миллионы строк, а юзеров много которые юзают данную процедуру ==> высокая конкуренция за tempdb и еще на диске места не так много.
26 фев 14, 11:21    [15630997]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
create proc ....(
  @res int OUTPUT
) as begin
select ....
set @res =@@ROWCOUNT
26 фев 14, 11:22    [15631008]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Glory
Member

Откуда:
Сообщений: 104751
relief
Как без создания временных таблиц вернуть Селект и установить значение для OUTPUT параметра?

Написать селект и присвоить переменной значение

relief
Проблема в том, что резульат селекта может быть миллионы строк, а юзеров много которые юзают данную процедур

И где тут проблема ?

Сообщение было отредактировано: 26 фев 14, 11:23
26 фев 14, 11:23    [15631009]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
relief
Member

Откуда:
Сообщений: 1197
Maxx
create proc ....(
  @res int OUTPUT
) as begin
select ....
set @res =@@ROWCOUNT


не пойдет. у меня пейджинг. поэтому надо вернуть именно сколько попало под Селект.
26 фев 14, 11:38    [15631139]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
relief
Member

Откуда:
Сообщений: 1197
Glory
relief
Как без создания временных таблиц вернуть Селект и установить значение для OUTPUT параметра?

Написать селект и присвоить переменной значение

а как?

relief
Проблема в том, что резульат селекта может быть миллионы строк, а юзеров много которые юзают данную процедур

И где тут проблема ?


на диске места мало + tempdb итак перегружена по активности.
26 фев 14, 11:39    [15631152]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Glory
Member

Откуда:
Сообщений: 104751
relief
не пойдет. у меня пейджинг. поэтому надо вернуть именно сколько попало под Селект.

А как можно узнать, сколько записей получится без выполнения запроса ?
26 фев 14, 11:39    [15631153]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
relief
не пойдет. у меня пейджинг. поэтому надо вернуть именно сколько попало под Селект.

ну прости дорогой в хрустальный шар не глянул:)
26 фев 14, 11:41    [15631167]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Хе-хе. Паджинг это целая тяхнология. Решений реально много.
И всё кардинально зависит от задачи.

Реально пользователям надо знать точно сколько строк / страниц?
Для чего они этим пользуются?
Как они этим пользуются?
Какова архитектура приложения (клиентской части)?
Какие допустимые ограничения?
И т.п.

К примеру, можно сливать пэйджинг "наружу". Тогда запрос к базе будут редкими, ибо будут пользоваться подготовленными данными. И это опять таки можно сделать очень многими разными способами.

Самый фиговый вариант - это когда данные сами по себе динамичны.
НО и здесь кучу вопросов. Ибо паджинг итак будет прыгать под пальцами.
И тяжело стараться не сделать то, что в реале не нужно.
26 фев 14, 22:20    [15636033]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
VFl
Member

Откуда:
Сообщений: 126
relief
Как без создания временных таблиц вернуть Селект и установить значение для OUTPUT параметра?


Через FETCH можно. Когда FETCH первый раз вернет ошибку (прошел весь первый resultset), надо сделать FETCH снова, и там будет значение, которое вернула процедура. Что бы все миллионы строк не прходить, при первом resultset мозно сделать сразу FETCH LAST.
26 фев 14, 22:46    [15636155]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
VFl
Member

Откуда:
Сообщений: 126
Забыл написать - надо в процедуре сделать RETURN

create proc ....(
  @res int OUTPUT
) as begin
select ....
set @res =@@ROWCOUNT

RETURN @res


В T-SQL можно и так:
EXECUTE @VAR1 = [dbo].[USP_PROCEDURE_TO_RETURN]
26 фев 14, 23:07    [15636272]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
relief
Maxx
create proc ....(
  @res int OUTPUT
) as begin
select ....
set @res =@@ROWCOUNT


не пойдет. у меня пейджинг. поэтому надо вернуть именно сколько попало под Селект.


Пейджинг делай на клиенте.

Запрос невозможно выполнить в процедуре и его же отдать клиенту.
27 фев 14, 00:41    [15636692]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Mnior
Хе-хе. Паджинг это целая тяхнология. Решений реально много.
И всё кардинально зависит от задачи.


И ни одно решение реально по большому счёту не работает...
:-)
27 фев 14, 00:42    [15636696]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
MasterZiv
Mnior
И всё кардинально зависит от задачи.
И ни одно решение реально по большому счёту не работает...
Как вы в точку дополнили. "Разные решения работают по разному." ;)
Да, волшебной палочки нет.
Mnior
К примеру, можно сливать пэйджинг "наружу". Тогда запрос к базе будут редкими, ибо будут пользоваться подготовленными данными. И это опять таки можно сделать очень многими разными способами.
MasterZiv
Пейджинг делай на клиенте.
relief, вот видите, те же мысли. ;)
Только если у вас к примеру Web, то есть решения где эти функции берёт на себя, к примеру nginx (а не браузер), через пре-рендериг страниц. пример с потолка.

Выбор полноценно работающего варианта зависит от задачи.

VFl, вы не поняли на счёт процедуры.
1. Запрос в процедуре вернёт только одну страницу данных. И @@RowCount вернёт количество строк в этой странице, а надо всех строк без обрезания в одну страницу.
2. Возврат значения через RETURN в процедуре конечно можно, но плохая практика, ибо это чисто Int для возврата кодов ошибок её выполнения.
Обычно для скалярок так используют.
3. Ничем не лучше чем обыкновенный OUT параметр.
VFl
Через FETCH можно.
Курсоры бывают 3х видов.
1. Хранить текущий ключ, когда запрос топорный, отсортирован строго по ключу основной таблы.
2. Хранит во временной таблице все ключи строк. Уже много может занять в tempdb
3. Хранит все данные запроса во времянке. Ахтунг.
Есть нюансы, но основной смысл именно таков.

1й вариант может банально не пройти из-за любых маленьких особенностей запроса. Остальные - теже яйца (времянки) только в профиль.
VFl
Что бы все миллионы строк не прходить, при первом resultset мозно сделать сразу FETCH LAST.
Он будет проходить все миллионы строк, только скрыто от ваших глаз но ощутимо для TC.
Даже топорный Count(*) будет лучше. У него даже план запроса может быть более оптимальным.

Забудьте про курсоры уже наконец.
27 фев 14, 02:42    [15636989]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
VFl
Member

Откуда:
Сообщений: 126
Mnior
2. Возврат значения через RETURN в процедуре конечно можно, но плохая практика, ибо это чисто


Я, кстати, в поправке ошибся, делать
RETURN @res

не надо. Сейчас проверил на всякий случай. Если входная переменная объявлена как OUTPUT, она автоматически добавляется как последний recordset. Если OUTPUT переменных две, то последний FETCH надо делать тоже на 2 переменные, так вытягиваются обе. А значение RETURN через FETCH у меня не вытянулось.


Mnior
Забудьте про курсоры уже наконец.

Речь шла о возращении OUTPUT параметра обратно в клиентскую программу. Можно делать это через FETCH без открытия курсоров, даже если сама процедура ничего больше не возвращает. По крайней мере в PowerBuilder.

А вообще, обратитесь с такой просьбой в Microsoft, может они их отменят :) Если серьезно, то, наверно, в теории можно обойтись совсем без курсоров. Но на практике бывают ситуации, когда на существующей системе (да еще и на старых типах баз) надо что то быстро сделать, и переделывать систему возможности никакой нет. Тут часто помогают курсоры, хотя делаешь это с плохим настроением.
27 фев 14, 06:22    [15637109]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Что тут говорить про курсоры?!
Mnior правильно сказал. Сначала перебробуйте все прочие решения.

VFl, Вы наверно всё о курсорах знаете, да?

sp_cursorfetch (Transact-SQL)

Эту процедуру использует, например, такое Г, как J.D.Edwards Enterprise One.
Что-то меня тошнит... Пойду поближе к унитазу
27 фев 14, 09:37    [15637500]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
+ VFl
VFl
Если входная переменная объявлена как OUTPUT, она автоматически добавляется как последний recordset. Если OUTPUT переменных две, то последний FETCH надо делать тоже на 2 переменные, так вытягиваются обе. А значение RETURN через FETCH у меня не вытянулось.
Я ниуя не понял.

VFl
Речь шла о возращении OUTPUT параметра обратно в клиентскую программу.
Нет, речь шла о другом. OUT это преамбула и к делу отношения не имеет.
VFl
Можно делать это через FETCH без открытия курсоров, даже если сама процедура ничего больше не возвращает. По крайней мере в PowerBuilder.
Опять ниуя не понял.

FETCH и OUTPUT - как это связано???
Для меня это как сравнивать тёплое и мягкое между собой.
Даже возврат курсора через OUT и то нифига не вплетается.

И зачем побочный упоминание о PowerBuilder-е? Это что неотьемлема часть MS SQL?!
Или вы кроме него ничего не видели и думаете в рамках его извращений?
VFl
Если серьезно, то, наверно, в теории можно обойтись совсем без курсоров. Но на практике бывают ситуации, когда на существующей системе (да еще и на старых типах баз) надо что то быстро сделать, и переделывать систему возможности никакой нет. Тут часто помогают курсоры, хотя делаешь это с плохим настроением.
Ну это не повод чтобы упоминать о них. Людей начинает резко тошнить, а молодняк как губка, потом тяжело от гадостей избавить.
Лучше стойко до последнего даже не заикаться.
27 фев 14, 14:26    [15639870]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Mnior
VFl
Если входная переменная объявлена как OUTPUT, она автоматически добавляется как последний recordset. Если OUTPUT переменных две, то последний FETCH надо делать тоже на 2 переменные, так вытягиваются обе. А значение RETURN через FETCH у меня не вытянулось.
Я ниуя не понял.
ИМХО, VFl толкует о курсоре на стороне клиента...
27 фев 14, 14:49    [15640081]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap
sp_cursorfetch (Transact-SQL)
invm
ИМХО, VFl толкует о курсоре на стороне клиента...
Да.
Тема подымалась и не раз. Я даже сам какие-то ссылки приводил в своё время... но блин, ничего не могу найти о принципах передачи данных от запросов на клиент.
Где BOL дока о низкоуровневом API? А главное об их принципах работы.
27 фев 14, 17:26    [15641789]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
К примеру SQLFetch это ODBC обёртка.
От неё ожидать что-то внятное врятли можно.
Можно найти ADO API:
CursorTypeEnum
MoveFirst, MoveLast, MoveNext и MovePrevious
Но там не сказано явно как это всё внутрях фунчиклирует, хотя сказано:
Use the MoveLast method to move the current record position to the last record in the Recordset. The Recordset object must support bookmarks or backward cursor movement; otherwise, the method call will generate an error.

adOpenForwardOnly0Default. Uses a forward-only cursor. Identical to a static cursor, except that you can only scroll forward through records. This improves performance when you need to make only one pass through a Recordset.
И adOpenForwardOnly единственный быстрый (прямой).
CursorLocationEnum
И особенно ExecuteOptionEnum

Т.е. между сервером и даже sql провайдером и уровнем приложения целый комбайн.

Если использовать неправильно, то будет или буферизация на уровне сервера (явно или косвенно) или на уровне клиента. Что ТС явно хочет избежать, как непродуктивное использование.

Так что решение в виде "пре-рендериг" (с общей идеей не убивать и расшаривать "буфер") или отдельно считывать "количество строк" (которые можно тоже кешировать) будет более оправданным.

Такое понятное из жизни явление как стопка страниц, с такими понятными вещами как нумерация страниц и быстрое перелистывание к любой. В мире кода это не так эффективно как кажется - ибо это и есть "пре-рендериг".
И поэтому возникает мнения аля "ни одно решение реально по большому счёту не работает...", ибо хочеца волшебства в обход законам природы. ИМХО

КО
27 фев 14, 18:52    [15642310]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть SELECT и OUTPUT параметр  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Вот у оракакла, как я понимаю но могу ошибаться, всё намного топорнее, ибо он настоящий курсорщик.
Что SELECT что явный курсор, что чтение с клиента - всё есть один тип программного курсора.

Жду пока не ворвётся в пост гуру, и не расскажет подробно, или скинет ссылку, как происходит взаимодействие SELECT пипелайна с клиентом, курсорами и вообще ...
27 фев 14, 18:57    [15642341]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить