Недопустимое использование оператора с побочным действием

Недопустимое использование оператора с побочным действием thumbnail

als-a
Member

Откуда:
Сообщений: 7

Не пойму что не так (ногами не бейте вчера MsSql Server 2005 Rus поставил)
в Microsoft SQL Server Management Studio (9.00.2047.00) пытаюсь создать фунцию
вот текст
— ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
— =============================================
CREATE FUNCTION GET_ID
(
— Add the parameters for the function here
)
RETURNS int
AS
BEGIN
DECLARE @a int, @ID_COUNT_0 int
Select @ID_COUNT_0=ID_COUNT_0 from dbo.Counters
Set @a=@ID_COUNT_0
Set @ID_COUNT_0=@ID_COUNT_0+1

Update dbo.Counters set ID_COUNT_0 = @ID_COUNT_0
RETURN (@a)

END
GO

Нажимаю кнопочку “Показать предполагаемый план выполнения” и получаю следующее сообщение:

Сообщение 443, уровень 16, состояние 15, процедура GET_ID, строка 17
Недопустимое использование оператора с побочным действием или зависимого от времени в “UPDATE” в функции.

Таблица dbo.Counters состоит из одного столбца int в ней одна запись где ID_COUNT_0=1
Что не так ?

daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

в функциях запрещены dml операторы над постоянными таблицами.

Posted via ActualForum NNTP Server 1.4

Glory
Member

Откуда:
Сообщений: 104760

als-a

Сообщение 443, уровень 16, состояние 15, процедура GET_ID, строка 17
Недопустимое использование оператора с побочным действием или зависимого от времени в “UPDATE” в функции.

Таблица dbo.Counters состоит из одного столбца int в ней одна запись где ID_COUNT_0=1
Что не так ?

А что непонятного в сообщении
Недопустимое использование оператора с побочным действием или зависимого от времени в “UPDATE”

als-a
Member

Откуда:
Сообщений: 7

а процедуры ?

Glory
Member

Откуда:
Сообщений: 104760


Двести

daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

>а процедуры ?

в процедурах – можно. но процедуры нельзя напрямую в запросах использовать.

Posted via ActualForum NNTP Server 1.4

daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

>а процедуры ?

или вы в смысле – вызывать процедуры в функциях?
вызов процедур там тоже запрещен. расширенные (extended) только можно.

Posted via ActualForum NNTP Server 1.4

als-a
Member

Откуда:
Сообщений: 7

То есть запихнуть Update в процедуру и вызвать процедуру из функции тоже не прокатит ?

проходящий.

Guest

als-a
Не пойму что не так (ногами не бейте вчера MsSql Server 2005 Rus поставил)
Set @ID_COUNT_0=@ID_COUNT_0+1

Update dbo.Counters set ID_COUNT_0 = @ID_COUNT_0

Ничего не знаю, ничего не понимаю, но первое что сделаю – свой генератор последовательностей.
Без него ж никак! 🙂

Glory
Member

Откуда:
Сообщений: 104760

als-a
То есть запихнуть Update в процедуру и вызвать процедуру из функции тоже не прокатит ?

Можно один раз открыть в хелпе перечень ограничений udf-ов и узнать о них всех сразу

pkarklin
Member

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

проходящий.
Ничего не знаю, ничего не понимаю, но первое что сделаю – свой генератор последовательностей.
Без него ж никак! 🙂

ну и делайте на основе процедуры.

als-a
Member

Откуда:
Сообщений: 7

Ну по поводу Ничего не знаю, ни чего не понимаю: Я более 10 лет работал с Oracle.
а по поводу но первое что сделаю – свой генератор последовательностей.
Без него ж никак! : на чем-то надо ж эксперементы проводить…

Кстати в Oracle в фунции можно писать что угодно, чего-то парни из Microsoft не додумали …

Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37094

als-a
Ну по поводу Ничего не знаю, ни чего не понимаю: Я более 10 лет работал с Oracle.
а по поводу но первое что сделаю – свой генератор последовательностей.
Без него ж никак! : на чем-то надо ж эксперементы проводить…

Кстати в Oracle в фунции можно писать что угодно, чего-то парни из Microsoft не додумали …

У вас два варианта: или отвыкать от того, к чему вы привыкли на оракле, или писать дальше на оракле.

pkarklin
Member

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

автор
а по поводу но первое что сделаю – свой генератор последовательностей.

М.б. свойством IDENTITY(1, 1) обойдетесь?!

als-a
Member

Откуда:
Сообщений: 7

да обойтись можно то можно а как же эксперименты ?

Glory
Member

Откуда:
Сообщений: 104760

als-a
да обойтись можно то можно а как же эксперименты ?

После 10лет работы с Oracle это скорее будут не эксперименты, а попытки эмулировать Oracle на MSSQL

pkarklin
Member

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

als-a
да обойтись можно то можно а как же эксперименты ?

О каких экспериментах идет речь?! Попытка реализовать на MS SQL Oracle?

als-a
Member

Откуда:
Сообщений: 7

Гавриленко Сергей Алексеевич
als-a
Ну по поводу Ничего не знаю, ни чего не понимаю: Я более 10 лет работал с Oracle.
а по поводу но первое что сделаю – свой генератор последовательностей.
Без него ж никак! : на чем-то надо ж эксперементы проводить…

Кстати в Oracle в фунции можно писать что угодно, чего-то парни из Microsoft не додумали …

У вас два варианта: или отвыкать от того, к чему вы привыкли на оракле, или писать дальше на оракле.

В другое место ушел работать, на Oracle золотого запаса здесь не хватает. Тут базы под акцесом сделаны, так то это не очень хорошо … Так что надо потихонечку мигрировать куда – нибудь, похоже на MS SQL Server …..

als-a
Member

Откуда:
Сообщений: 7

да и под нарезанные задачи – Oracle все равно что из пушки по воробьям …

pkarklin
Member

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

als-a
Так что надо потихонечку мигрировать куда – нибудь, похоже на MS SQL Server …..

Тогда резко забываем об Oracle и осваиваем “парадигму” MS SQL. 😉

tpg
Member

Откуда: Novosibirsk
Сообщений: 23902

als-a
…чего-то парни из Microsoft не додумали …

С чего это вы решили, что не додумали? Половина команды разработки сиквела – это аккурат бывшие разработчики оракла. Видимо таким образом они решили отказаться от тупиковых путей (перейдя в MS) 😉

SQLMantis
Member

Откуда: Москва
Сообщений: 239

Если бы подобное было разрешено, что вернул бы запрос:
select GET_ID, ID_COUNT_0 from dbo.Counters ?

Источник

Multy
Member [заблокирован]

Откуда:
Сообщений: 420

Пытаемся создать функцию типа
Create FUNCTION dbo.Ins
(
@Pr1 Int,
@Pr2 Int
)
RETURNS @Rez1 TABLE
(
Rez1 Int,
Rez2 Int
)
AS
BEGIN
insert into dbo.Rez(Rez1,Rez2) Values(@Pr1,@Pr2)
insert into @Rez Values(1,1)
RETURN
END
Получаем ошибку:
Сообщение 443, уровень 16, состояние 15, процедура Insert, строка 13
Недопустимое использование оператора “INS”, оказывающего побочное действие, в функции.
Это можно как-нибудь обойти или отключить?
Alter Procedure dbo.Ins
(
@Pr1 Int,
@Pr2 Int
)
AS
BEGIN
insert into dbo.Rez(Rez1,Rez2) Values(@Pr1,@Pr2)
Select * from dbo.Rez
END
Или инсерты взможны только в процедурах?

Nailbomb

Guest

в функциях инсерты делать нельзя

Multy
Member [заблокирован]

Откуда:
Сообщений: 420

Nailbomb
в функциях инсерты делать нельзя

Это они не доработали, или скорее переработали…

Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37094

Multy
Nailbomb
в функциях инсерты делать нельзя

Это они не доработали, или скорее переработали…

Да нет, это просто кто-то хелп не дочитал.

Козьма Прутков
Member

Откуда: Москва
Сообщений: 186

Multy,

а точно надо писать dbo.Rez а не @Rez1? В результирующую таблицу инсенртить можно, а в остальные – нет.

Create FUNCTION dbo.Ins
(
@Pr1 Int,
@Pr2 Int
)
RETURNS @Rez1 TABLE
(
Rez1 Int,
Rez2 Int
)
AS
BEGIN
insert into @Rez1(Rez1,Rez2) Values(@Pr1,@Pr2)
insert into @Rez1 Values(1,1)
RETURN
END

Multy
Member [заблокирован]

Откуда:
Сообщений: 420

Козьма Прутков
Multy,

а точно надо писать dbo.Rez а не @Rez1? В результирующую таблицу инсенртить можно, а в остальные – нет.

Create FUNCTION dbo.Ins
(
@Pr1 Int,
@Pr2 Int
)
RETURNS @Rez1 TABLE
(
Rez1 Int,
Rez2 Int
)
AS
BEGIN
insert into Rez1(Rez1,Rez2) Values(@Pr1,@Pr2)
insert into @Rez1 Values(1,1)
RETURN
END

В результирующию то понятно, смысл был как раз в побочную таблицу.
Канешна побочные действия функции считается плохой стиль, но вот бывает, что надо.
Попробуем процедуры.

Козьма Прутков
Member

Откуда: Москва
Сообщений: 186

Multy, а что за задача такая, при которой надо что-то менять в обычных таблицах? Уж не генератор ли каких номеров, или упаси бог ключей, вы пытаетесь написать?

проходящий.

Guest

Multy
Канешна побочные действия функции считается плохой стиль, но вот бывает, что надо.

И есть достаточное обоснование такой надобности? Можно его глянуть?

Пятница_13

Guest

Козьма Прутков,
А вот тут подробнее ! Про ключи особенно.

Aleksey-K
Member

Откуда: Москва
Сообщений: 3116

Козьма Прутков
Multy,

а точно надо писать dbo.Rez а не @Rez1? В результирующую таблицу инсенртить можно, а в остальные – нет.

Это не совсем верная информация.
Вы можете в функции создавать переменные типа таблица ( DECLARE @MyTable (…. ) ) и писать в них.
С уважением, Алексей

Козьма Прутков
Member

Откуда: Москва
Сообщений: 186

Aleksey-K, ладно уж придираться-то, я оперирую в терминах вопроса, а не пытаюсь пересказать BOL 🙂

Козьма Прутков
Member

Откуда: Москва
Сообщений: 186

Пятница_13
Козьма Прутков,
А вот тут подробнее ! Про ключи особенно.

Даже не знаю, что ответить. Может, лучше вопрос переформулировать?

Есть просто любители писать генераторы ключей, 99% которых просто не знают, как воспользоваться уже имеющимися возможностями MSSQL, или возможностями технологии разработки кода, который работает с БД. Поскольку любителей таких много – потому сразу и спрашиваю.

Пятница_13

Guest

Козьма Прутков
Пятница_13
Козьма Прутков,
А вот тут подробнее ! Про ключи особенно.

Даже не знаю, что ответить. Может, лучше вопрос переформулировать?

Есть просто любители писать генераторы ключей, 99% которых просто не знают, как воспользоваться уже имеющимися возможностями MSSQL, или возможностями технологии разработки кода, который работает с БД. Поскольку любителей таких много – потому сразу и спрашиваю.

Да, надо признать – я один из тех. А может просто привычка после Firebird-а и Oracle-а.
Буду признателен если разъясните какие возможности есть в MSSQL, дабы не изменять привычкам и не в ущерб производительности.

Козьма Прутков
Member

Откуда: Москва
Сообщений: 186

Пятница_13, не вижу смысла своими словами рассказывать, почитайте в BOL про identity, @@identity, scope_identity(). А также uniqueidentifier, newid() если хочется глобальной уникальности при невысокой производительности. Будут конкретные вопросы – задавайте уже их.

Пятница_13

Guest

Козьма Прутков,

Предлагаете изменить привычкам ?
В качестве генераторов попробовал использовать несколько таблиц с автоинкриментными полями, для получения нового значения просто добавлял запись и получал с помощью SCOPE_IDENTITY в ХП. Результат вроде приемлемый , но все же как-то не красиво …

Glory
Member

Откуда:
Сообщений: 104760

Пятница_13
Козьма Прутков,

Предлагаете изменить привычкам ?
В качестве генераторов попробовал использовать несколько таблиц с автоинкриментными полями, для получения нового значения просто добавлял запись и получал с помощью SCOPE_IDENTITY в ХП. Результат вроде приемлемый , но все же как-то не красиво …

Непривычно == некрасиво ? Красивость мереется по длине кода ?

Пятница_13

Guest

Glory
Пятница_13
Козьма Прутков,

Предлагаете изменить привычкам ?
В качестве генераторов попробовал использовать несколько таблиц с автоинкриментными полями, для получения нового значения просто добавлял запись и получал с помощью SCOPE_IDENTITY в ХП. Результат вроде приемлемый , но все же как-то не красиво …

Непривычно == некрасиво ? Красивость мереется по длине кода ?

В т.ч. и по длине кода ))
Но главное – производительность.
Вот и решил спросить совета. Может такой подход имеет право на жизнь ? )

Источник

ValGer
Member

Откуда: Псков
Сообщений: 468

Казалось бы тривиальная задачка.
Хочу создать функцию, которая бы выдавала наружу код новой записи в таблице. Код автоинкрементный, с шагом +1. Это достигается чтением @@IDENTITY после создания новой строки. Пишу функцию (в студии SQL 2008 R2):

ALTER FUNCTION [dbo].[НомерНовогоРаботника]
(
)
RETURNS numeric
AS
BEGIN

INSERT INTO dbo.MAIN
(НомерРайона, НомерРегиона, КодШколы, Фамилия, ИмяОтчество,
Пол, ДатаРождения, ОсновнаяДолжность)
VALUES
(1, 60, 1, ‘Анекто’, ‘Некто Нектович’, ‘Ж’, ‘01.01.1990’, 8)

RETURN @@IDENTITY
END

Проверка синтаксиса в студии говорит, что всё хорошо, но как только пытаюсь выполнить (то есть записать эту функцию в базу – ALTER) выдаётся странная ошибка:

Сообщение 443, уровень 16, состояние 15, процедура НомерНовогоРаботника, строка 7
Недопустимое использование оператора “INSERT”, оказывающего побочное действие, в функции
.

Проверил отдельно INSERT – всё прекрасно вставляется.
Что это может означать?

locky
Member

Откуда: Харьков, Украина
Сообщений: 62034

ValGer
Что это может означать?

это означает ровно то, что написано – “нельзя использовать insert в функции” – равно как и еще некоторый набор стейтментов
это прекрасно описано в BOL в разделе по созданию UDF

iap
Member

Откуда: Москва
Сообщений: 47010

ValGer,

из UDF нельзя менять данные в постоянных и временных таблицах.

ValGer
Member

Откуда: Псков
Сообщений: 468

locky,

Спасибо, просветили! Читая книжки, наверно, пропустил.
Видимо, в процедуре можно?
Кстати что такое BOL? Дайте ссылочку.
С уважением …

locky
Member

Откуда: Харьков, Украина
Сообщений: 62034

ValGer
locky,

Спасибо, просветили! Читая книжки, наверно, пропустил.
Видимо, в процедуре можно?
Кстати что такое BOL? Дайте ссылочку.
С уважением …

Топ 10, вопрос №4

ValGer
Member

Откуда: Псков
Сообщений: 468

iap,

Здесь я побывал, но нигде членораздельные слова о том, что INSERT нельзя использовать в функциях не встретил. А сообщение очень завуалированное – спасибо просветили.

Ennor Tiegael
Member

Откуда:
Сообщений: 3287

ValGer,

На самом деле, insert использовать в функциях можно, но только с табличными переменными (они пока по определению локальны).

Общее же правило – выполнение функции не должно приводить к изменению чего-либо за ее пределами – сформулировано в доке довольно четко.

locky
Member

Откуда: Харьков, Украина
Сообщений: 62034

ValGer
iap,

Здесь я побывал, но нигде членораздельные слова о том, что INSERT нельзя использовать в функциях не встретил. А сообщение очень завуалированное – спасибо просветили.

https://msdn.microsoft.com/ru-ru/library/ms186755(v=sql.100).aspx

разделы “Совместимость” и “Ограничения”

https://msdn.microsoft.com/ru-ru/library/ms191320(v=sql.100).aspx

раздел “Рекомендации”: “Изменения таблиц баз данных, операции с курсорами, не являющимися локальными для данной функции, отправка электронной почты, попытка изменения каталога, формирование результирующего набора, возвращаемого пользователю — это примеры действий, выполнение которых внутри функции невозможно.”

SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8771

Перепишите на хранимую процедуру,- проблем со вставкой не будет.
первой строкой set nocount on
в последней – select @NewId (который у Вас @@identity)

Источник

MsGuns
Member

Откуда: г.Чернигов
Сообщений: 113

Вот функция:
USE [TelBook]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[UsF_Test]
(
@FieldName sysname, — Имя поля, по которому делать фильтрацию (where)
@FieldValue varchar(max), — Значение для фильтрации
@FieldSort sysname, — Имя поля для сортировки (order by)
@Nlist int, — Номер листа, который требуется вернуть
@QRows int — Кол-во строк на листе
)
RETURNS
@RetTable TABLE
(
FIO_ID int,
FIO_FAM varchar(255),
FIO_Name [varchar](255),
FIO_SName [varchar](255),
FIO_RoomNo [varchar](8),
FIO_PersAdrs [varchar](1024) NULL,
FIO_Pos [int] NULL,
FIO_OUT [varchar](4) NULL,
FIO_DateOUT [date] NULL,
FIO_DEP [int] NULL,
FIO_MI [int] NULL,
FIO_Mo [int] NULL,
FIO_OP [int] NULL,
FIO_RG [int] NULL,
FIO_UPR [int] NULL,
FIO_SUB [int] NULL,
FIO_Res1 [varchar](1024) NULL,
FIO_Res2 [varchar](16) NULL,
FIO_Res3 [varchar](16) NULL,
FIO_Res4 [varchar](16) NULL
)

AS
BEGIN
declare @SSQL varchar(max)
set @SSQL = ‘Insert into’ +’@RetTable (FIO_FAM,FIO_Name)’ +’ Select * from FIO ‘
+’ Where ‘+@FieldName+ ‘ = ”’+@FieldValue+”’ order by ‘+@FieldSort
+’ offset ‘+ cast((@Nlist-1)*@QRows as varchar(10))+’rows fetch next ‘+cast(@Qrows as varchar(10))+’ rows only ‘
Exec (@SSQL)
RETURN
END

При попытке записать UDF на сервер выдает

Сообщение 443, уровень 16, состояние 14, процедура UsF_Test, строка 41
Недопустимое использование оператора “EXECUTE STRING”, оказывающего побочное действие, в функции.

Что делать ?

Спасибо за помощь

MsGuns
Member

Откуда: г.Чернигов
Сообщений: 113

Гавриленко Сергей Алексеевич
Делать динамический sql не в udf.

А в UDF никак ?

MsGuns
Member

Откуда: г.Чернигов
Сообщений: 113

Гавриленко Сергей Алексеевич
MsGuns,

Никак. Об этом даже в документации написано.

Спасибо.

vikkiv
Member

Откуда: London
Сообщений: 2739

MsGuns,

Exec/SP в функции не вставляется, (за искл. специальных), ну или CLR тогда
,а наоборот почти без проблем (вызов функций в SP)

Сообщение было отредактировано: 4 янв 20, 18:15

Владислав Колосов
Member

Откуда:
Сообщений: 8002

MsGuns,

такие вещи недопустимо использовать в принципе при разработке для бизнеса.

MsGuns
Member

Откуда: г.Чернигов
Сообщений: 113

Владислав Колосов
MsGuns,

такие вещи недопустимо использовать в принципе при разработке для бизнеса.

А почему собственно ? Этот динамический запрос выполняется сугубо на сервере, доступа к хранимке со стороны клиента отсутствует в принципе ибо трехзвенка (ASP.NET MVC). Что тут противоречит принципам “разработок для бизнеса” ?

stenford
Member

Откуда: урал
Сообщений: 2839

MsGuns

А почему собственно ? Этот динамический запрос выполняется сугубо на сервере, доступа к хранимке со стороны клиента отсутствует в принципе ибо трехзвенка (ASP.NET MVC). Что тут противоречит принципам “разработок для бизнеса” ?

потому-что динамический sql, где поля и данные подставляются произвольно – это самоубийство безопасности, тут не только данные можно выгрести какие угодно, но еще саму базу дропнуть

Источник

Читайте также:  Побочные действия энап н