Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
вводная: стороннее приложение вызывает мою х.п. через АДО. в профайлере выловил что непосредственно перед запуском идёт попытка получения метаданных с помощью SET FMTONLY ON
set fmtonly on
EXEC dbo.proc1 
set fmtonly off
в результате генерится ошибка (неважно какая). если выполнять без set fmtonly on - всё работает как и ожидалось(без ошибок). Исключить set fmtonly on не могу, т.к. этот код генерирует стороннее приложение
Вот код для тестирования
CREATE  FUNCTION dbo.f1() 
RETURNS varchar(4)
AS
BEGIN
DECLARE	@s2 AS varchar(4),@n AS int
SET @n = charindex(',','')
IF @n > 1 SET @s2 = LEFT('',@n-1)
ELSE	SET @s2 = ''
RETURN @s2
END
GO

CREATE   PROCEDURE dbo.proc1
AS
DECLARE @s AS varchar(4)
SET @s = dbo.f1()
GO

set fmtonly on
EXEC dbo.proc1 
set fmtonly off
GO

drop procedure proc1
go
drop function dbo.f1
GO

Кто сталкивался, подскажите как можно заставить работать х.п.?
1 фев 07, 14:11    [3725694]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
CREATE   PROCEDURE dbo.proc1
AS
SET FMTONLY OFF
DECLARE @s AS varchar(4)
SET @s = dbo.f1()
GO
1 фев 07, 14:14    [3725720]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
как исправить этот конкретный код я уже придумал: LEFT('',@n-1*sign(@n))
интересует более глобальный вопрос: как заставить работать х.п. без ошибок в режиме set fmtonly on?
Ситуаций когда работает без fmtonly и не работает с fmtonly можно придумать очень много.
Например рекурсия. Т.е. через АДО невозможно вызывать х.п. где используется рекурсия???
CREATE   PROCEDURE dbo.proc2
AS
if 1=0 exec dbo.proc2
GO

set fmtonly on
EXEC dbo.proc2
set fmtonly off
GO

drop procedure proc2
go

П.С. MS SQL Server 2000 SP4 (8.00.2187)
1 фев 07, 14:16    [3725734]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
pkarklin
CREATE   PROCEDURE dbo.proc1
AS
SET FMTONLY OFF
DECLARE @s AS varchar(4)
SET @s = dbo.f1()
GO
быстро :-)
а если речь идёт о функциях?
в них SET FMTONLY OFF не поставишь :-(
1 фев 07, 14:18    [3725746]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
автор
Т.е. через АДО невозможно вызывать х.п. где используется рекурсия???


Ваша процедура ведь не возвращает набор данных. Можно. ExecuteOption должен включать в себя параметр adExecuteNoRecords.
1 фев 07, 14:21    [3725769]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
pkarklin
CREATE   PROCEDURE dbo.proc1
AS
SET FMTONLY OFF
DECLARE @s AS varchar(4)
SET @s = dbo.f1()
GO
это ещё плохо тем, что функции/процедуры будут выполнятся 2 раза.
1 фев 07, 14:23    [3725794]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
pkarklin
автор
Т.е. через АДО невозможно вызывать х.п. где используется рекурсия???


Ваша процедура ведь не возвращает набор данных. Можно. ExecuteOption должен включать в себя параметр adExecuteNoRecords.
ок :-) с данным конкретным примером разобрались
а другая х.п. возвращает данные и её с adExecuteNoRecords запускать нельзя
кроме того, код, работающий с АДО я не контролирую и поставить adExecuteNoRecords не могу :-(
1 фев 07, 14:25    [3725807]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Stimo
Member

Откуда: Leeds
Сообщений: 814
автор
adExecuteNoRecords

eoExecuteNoRecords - если вы про дельфи =)
1 фев 07, 14:27    [3725819]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Stimo
автор
adExecuteNoRecords

eoExecuteNoRecords - если вы про дельфи =)


В Delphi eo..., в ADO ad...
1 фев 07, 14:30    [3725838]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Dmitry Biryukov

а другая х.п. возвращает данные и её с adExecuteNoRecords запускать нельзя
кроме того, код, работающий с АДО я не контролирую и поставить adExecuteNoRecords не могу :-(


Тогда Вам необходимо так писать код, чтобы он работал в не зависимости от этого SET.
1 фев 07, 14:31    [3725848]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Stimo
Member

Откуда: Leeds
Сообщений: 814
pkarklin
Stimo
автор
adExecuteNoRecords

eoExecuteNoRecords - если вы про дельфи =)


В Delphi eo..., в ADO ad...

Может, в ADO 128, в VB ad... ?
1 фев 07, 14:44    [3725969]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
pkarklin
Тогда Вам необходимо так писать код, чтобы он работал в не зависимости от этого SET.
Если другого выхода действительно нет, то давайте поговорим о то КАК писать код, чтобы он работал вне зависимости от этого SET? поделюсь пока личными наблюдениями или гипотезами:
1. временные таблицы не использовать
2. рекурсию не использовать
3. иметь в виду, что DDL команды, а также INSERT и DELETE не выполняются
4. выполняются обе части оператора IF (после IF и после ELSE) независимо от значения условия

кто исправит/дополнит?
1 фев 07, 16:53    [3727086]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
up!
неужели никто не пишет хранимые процедуры для других приложений? все только для себя?
16 фев 07, 13:51    [3796378]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
ziktuw
Member

Откуда:
Сообщений: 3552
Delphi шлет первый вызов, обрамленный SET FMTONLY ON, SET FMTONLY OFF, чтобы получить метаданные - описания полей возвращаемого набора данных. Отсюда простой вывод - в дизайнере соответствующего TAdoDataSet (TAdoQuery, или чего там еще) надо сформировать описания полей - fieldsdef. Тогда Дельфи уже не станет делать такой левый вызов в рантайме.


----------------------------------------------------------------
Да полно-те Вам. Не стоит благодарности.
16 фев 07, 16:53    [3798015]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
спасибо. но повторяю ещё раз: у меня нет исходников приложения, которое вызывает мои ХП. И ничего в нём менять я не могу по разным причинам.
неужели никто не пользуется 3rd-party applications?
у всех свои доморощенные приложения на Delphi,C# и т.д. ?

Задача в том каким образом писать х.п., чтобы установка опции set fmtonly on хотя бы не генерировала ошибок
16 фев 07, 16:57    [3798050]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
ziktuw
Member

Откуда:
Сообщений: 3552
Поступают в жизни, как pkarklin уже отписал - принудительно возвращают SET FMTONLY OFF в начале процедуры.

Есть и другой путь. Проанализуй этот код:

declare @o int
SET FMTONLY ON
select 1
set @o=@@rowcount
SET FMTONLY OFF
select 1
select @o, @@rowcount

Я толкую о том, что можно на ходу определять, установлен FMTONLY или нет. И в зависимости от этого ветвить код. А приложению надо всего лишь при выставлнном SET FMTONLY ON вернуть всего лишь пустой набор данных с правильными метаданными полей.

Кстати, @@OPTIONS не кажет установку FMTONLY, увы.


----------------------------------------------------------------
Да полно-те Вам. Не стоит благодарности.

Сообщение было отредактировано: 16 фев 07, 17:22
16 фев 07, 17:16    [3798214]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31985
Dmitry Biryukov
up!
неужели никто не пишет хранимые процедуры для других приложений? все только для себя?
Честно говоря, непонятен вопрос. Что значит "для себя"??? Я пишу хранимые приложения для разработок нашей компании, но клиентских приложений не писал много лет. Это для себя или для других?

Теперь по вопросу:
Dmitry Biryukov
давайте поговорим о то КАК писать код, чтобы он работал вне зависимости от этого SET? поделюсь пока личными наблюдениями или гипотезами:
1. временные таблицы не использовать
2. рекурсию не использовать
3. иметь в виду, что DDL команды, а также INSERT и DELETE не выполняются
4. выполняются обе части оператора IF (после IF и после ELSE) независимо от значения условия
кто исправит/дополнит?


Если приложение требует, что-бы без выполнения можно было получить метаданные о результатах запроса, то выход один - именно так писать приложения. Соответственно, как вы говорите - почти ничего нельзя использовать.

Или вариант - ставить SET FMTONLY OFF в процедурее - хотя, как правильно говорят, процедуры будут выполняться 2 раза. А если это оплата заказа???

Или извращаться, чтобы возвращали хоть какие-то метаданные (правильные нельзя - это принципиально невозможно сделать всегда, без исключений).

Но вообще, как правило, приложения написаны нормально и этого не требуют. А если кто-то криво пишет, ему можно об этом сообщить.
16 фев 07, 17:25    [3798293]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
to Dibrov:

ок. спасибо за помощь, но:
1. выставить FMTONLY невозможно в функциях
2. если выставить FMTONLY OFF, то все запросы внутри х.п. будут выполнятся 2 раза (первый раз при получении метаданных, второй непосредственно при выполнении). т.е. производительность упадёт в 2 раза.

допустим в коде можно проверить значение FMTONLY, но как его не ветви, будут "выполнены" все statements.
попробуйте такой код:
SET FMTONLY ON

declare @bit_FMTONLY_ON bit , @s varchar(1), @n int
select 1
set @bit_FMTONLY_ON = cast(1-@@rowcount as bit)
IF @bit_FMTONLY_ON = 1
	SET @s = ''
ELSE
BEGIN
	SET @s = getdate()
	SET @n = charindex(',',@s)
	IF @n > 0	
		SET @s = left(@s,@n-1)
	ELSE
		SET @s = ''
END
Server: Msg 536, Level 16, State 3, Line 13
Invalid length parameter passed to the substring function.

т.е. ветвить код можно, но к желаемому результату это не приводит, т.к. (по одной из гипотез) выполняются обе части оператора IF (после IF и после ELSE) независимо от значения условия
16 фев 07, 17:42    [3798414]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
2 alexeyvg: вопрос про "для себя" снимается, т.к. он второстепенен. но в моём понимании ваш случай попадает в категорию "для себя", т.к. можно договорится с отделом разработки (одна же компания) чтобы они код писали с учётом "туда не ходи, сюда ходи" (с)
не отвлекаемся :-)

alexeyvg
Если приложение требует, что-бы без выполнения можно было получить метаданные о результатах запроса, то выход один - именно так писать приложения.
Ещё раз: приложение (BusinessObjects XI) менять не могу. точка. и никак не могу повлиять на разработчиков (так пиши, так не пиши) тоже не могу.

А если вы имели в виду: "именно так писать хранимые процедуры", то я с вами согласен и спрашиваю: как именно? в каждом конкретном случае натыкаюсь на очередные грабли. ведь в режиме FMTONLY ON отладка не работает и угадать где и в чём ошибка не всегда просто.

alexeyvg
Или вариант - ставить SET FMTONLY OFF в процедурее - хотя, как правильно говорят, процедуры будут выполняться 2 раза. А если это оплата заказа???
вариант плохой, я с вами согласен, но как запасной мне подойдёт - у меня все процедуры генерируют отчёты

автор
Или извращаться, чтобы возвращали хоть какие-то метаданные (правильные нельзя - это принципиально невозможно сделать всегда, без исключений).
вот и извращаюсь. в моём случае возможно: структура result set'а всегда одна и та же.

alexeyvg
Но вообще, как правило, приложения написаны нормально и этого не требуют. А если кто-то криво пишет, ему можно об этом сообщить.
интересно что кривее написано: ms sql или business objects? В любом случае жаловаться некому и никто не послушается :-(
16 фев 07, 17:53    [3798514]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31985
Dmitry Biryukov
alexeyvg
Если приложение требует, что-бы без выполнения можно было получить метаданные о результатах запроса, то выход один - именно так писать приложения.
Ещё раз: приложение (BusinessObjects XI) менять не могу. точка. и никак не могу повлиять на разработчиков (так пиши, так не пиши) тоже не могу.
Повлиять очень просто, только это не в вашей компетенции, наверное.

В принципе, в этом нет никаких проблем - ведь страдаете не вы, страдает бизнес вашей компании.

Можно использовать какие-то пути обхода, которые вам подсказали, можно не использовать фичи, которые есть в MSSQL; для вас лично ведь это проблем не создаёт?

Не принимайте близко к сердцу :-)

Dmitry Biryukov
alexeyvg
Но вообще, как правило, приложения написаны нормально и этого не требуют. А если кто-то криво пишет, ему можно об этом сообщить.
интересно что кривее написано: ms sql или business objects? В любом случае жаловаться некому и никто не послушается :-(
Да причём тут микрософт??? А если из приложеиня будут слать set noexec on и удивляться, почему это не работает??? Просто у них руки кривые - талантливые студенты, наверное, это их первый Бизес-Объект :-)
16 фев 07, 18:30    [3798771]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
alexeyvg, не отвлекайтесь, пожалуйста, от первоначального вопроса.
а если ответить на него не в вашей компетенции, то надо это признать, а не делать выводы о кривизне продукта, с которым вы незнакомы.
16 фев 07, 18:44    [3798862]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Glory
Member

Откуда:
Сообщений: 104751
Dmitry Biryukov
to Dibrov:

ок. спасибо за помощь, но:
1. выставить FMTONLY невозможно в функциях
2. если выставить FMTONLY OFF, то все запросы внутри х.п. будут выполнятся 2 раза (первый раз при получении метаданных, второй непосредственно при выполнении). т.е. производительность упадёт в 2 раза.

По-моему, вы пытаетесь решить проблему через одно место. Т.е. генерировать метаданные, которые невозможно сгенерировать заранее.
И если клиентское приложение желает знать заранее то, чего нельзя заранее знать, то для этого как раз и генерируется ошибка. Также, как она может генерироваться при неправильном использовании процедуры. Например, при отсутствующем или неверно заданном параметре вызова
16 фев 07, 18:51    [3798908]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
Glory
По-моему, вы пытаетесь решить проблему через одно место. Т.е. генерировать метаданные, которые невозможно сгенерировать заранее.
И если клиентское приложение желает знать заранее то, чего нельзя заранее знать, то для этого как раз и генерируется ошибка. Также, как она может генерироваться при неправильном использовании процедуры. Например, при отсутствующем или неверно заданном параметре вызова
Не совсем так. метаданные возможно сгенерировать заранее и приложение должно знать заранее структуру возвращаемых процедурой данных. такова его бизнес-логика, которую изменить, увы, нельзя. К слову сказать, возвращаемая структура всегда одинакова...
А ошибка возникает из-за того, что при включенной опции FMTONLY ON сам движок сиквела "выполняет" инструкции, которые он никогда бы не выполнил при отключенной опции FMTONLY OFF. Запишу пример из первого поста в константах:
IF 0 > 1 SET @s2 = LEFT('',-1)
ELSE	SET @s2 = ''
Так вот инструкция SET @s2 = LEFT('',-1) по идее выполнятся не должна, а при включенном FMTONLY ON она выполняется и имеем ошибку Invalid length parameter passed to the substring function

P.S. ошибку с LEFT(,-1) я решил, но имеется масса других, а в общем хотелось бы получить некий рецепт как этих ошибок избегать или хотя бы быстро находить (в режиме FMTONLY ON отладка не работает. не работает также print)
16 фев 07, 19:04    [3798977]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Glory
Member

Откуда:
Сообщений: 104751
Dmitry Biryukov
Glory
По-моему, вы пытаетесь решить проблему через одно место. Т.е. генерировать метаданные, которые невозможно сгенерировать заранее.
И если клиентское приложение желает знать заранее то, чего нельзя заранее знать, то для этого как раз и генерируется ошибка. Также, как она может генерироваться при неправильном использовании процедуры. Например, при отсутствующем или неверно заданном параметре вызова
Не совсем так. метаданные возможно сгенерировать заранее и приложение должно знать заранее структуру возвращаемых процедурой данных. такова его бизнес-логика, которую изменить, увы, нельзя. К слову сказать, возвращаемая структура всегда одинакова...
А ошибка возникает из-за того, что при включенной опции FMTONLY ON сам движок сиквела "выполняет" инструкции, которые он никогда бы не выполнил при отключенной опции FMTONLY OFF.

Как можно узнать метаданные процедуры с ветвлением ? Какая из веток IF-а нужна приложению ?
Ваше приложение тогда не FMTONLY должно использовать, а парсить тексты процедур
16 фев 07, 19:13    [3799004]     Ответить | Цитировать Сообщить модератору
 Re: багофича FMTONLY  [new]
Dmitry Biryukov
Member

Откуда: Женева
Сообщений: 1752
Glory
Как можно узнать метаданные процедуры с ветвлением ? Какая из веток IF-а нужна приложению ?
Ваше приложение тогда не FMTONLY должно использовать, а парсить тексты процедур

ветвление определяет таблицы-источники и накладываемые фильтры, иногда значения колонок. НО! СТРУКТУРА результата всегда одинакова. Я бы с удовольствием переписал процедуры на табличные функции, но для увеличения производительности я использую динамический SQL...
16 фев 07, 19:17    [3799015]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить