Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Вопрос по хранимой процедуре (число прочтений - 4193 )
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Вопрос по хранимой процедуре
05. Августа 2009 :: 08:10
Печать  
Есть очень простая хранимая "процедура - скалярная функция"

Код
Выбрать все
CREATE FUNCTION [dbo].[Parents](@Child char(9))
RETURNS varchar(256)
AS
BEGIN
	DECLARE @res varchar(256)
	set @res  = ''

	while @Child <> '     0   '
		begin
			Select @Child = parentid from SC54250 where id = @Child
			set @res  = '''' + @Child + '''' + ',' + @res
		end

	RETURN Left(@res, Len(@res) - 1)
END
 



По переданному id, возвращает строку из родителей.
Как ее переделать, чтоб в нее передавать еще и имя таблицы справочника.
Я предполагаю, что можно использовать exec + cursor.
Есть, еще какие-то варианты?
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Вопрос по хранимой процедуре
Ответ #1 - 05. Августа 2009 :: 08:16
Печать  
Как вариант: также передавать в функцию. Получай имя таблички через MetaDataWork.ИмяТаблицыСправочника(ИмяСправочника)
Извиняюсь. Ступил.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Вопрос по хранимой процедуре
Ответ #2 - 05. Августа 2009 :: 08:18
Печать  
chessman писал(а) 05. Августа 2009 :: 08:10:
Есть очень простая хранимая "процедура - скалярная функция"

Код
Выбрать все
CREATE FUNCTION [dbo].[Parents](@Child char(9))
RETURNS varchar(256)
AS
BEGIN
	DECLARE @res varchar(256)
	set @res  = ''

	while @Child <> '     0   '
		begin
			Select @Child = parentid from SC54250 where id = @Child
			set @res  = '''' + @Child + '''' + ',' + @res
		end

	RETURN Left(@res, Len(@res) - 1)
END
 



По переданному id, возвращает строку из родителей.
Как ее переделать, чтоб в нее передавать еще и имя таблицы справочника.
Я предполагаю, что можно использовать exec + cursor.
Есть, еще какие-то варианты?

Никак если ты в функции поставишь 100 ( условно ) if по
какому либо параметру то получишь либо ужасный план выполнения либо
sql будет каждый раз перекомпилировать функцию.
Не надо перекладывать то что должен делать клиент
на сервер.
ИХМО у тебя должно быть 100 функций.
Клиент ( 1с.exe ) должен сформировать запрос с уже выбранной функцией.
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Вопрос по хранимой процедуре
Ответ #3 - 05. Августа 2009 :: 08:31
Печать  
угу, никак. Динамический скл не прокатит в функции. Прописать все справочники через if тож не лучший вариант. Имхо, нормально было бы сделать отдельную функцию под каждый справочник dbo.Parents54250, dbo.ParentsXXX и т.д.
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Вопрос по хранимой процедуре
Ответ #4 - 05. Августа 2009 :: 08:39
Печать  
а почему нельзя как-то так?

exec('Select parentid from ' + @SCname + ' where id = ' + @Child), а результат в курсор передать
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Вопрос по хранимой процедуре
Ответ #5 - 05. Августа 2009 :: 08:43
Печать  
нельзя динамический SQL юзать в функции, не скомпилится
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Вопрос по хранимой процедуре
Ответ #6 - 05. Августа 2009 :: 08:56
Печать  
alexdd писал(а) 05. Августа 2009 :: 08:43:
нельзя динамический SQL юзать в функции, не скомпилится


Ты прав, в BOLе написано

Цитата:
The following statements are allowed in the body of a multi-statement function. Statements not in this list are not allowed in the body of a function:

Assignment statements.


Control-of-Flow statements.


DECLARE statements defining data variables and cursors that are local to the function.


SELECT statements containing select lists with expressions that assign values to variables that are local to the function.


Cursor operations referencing local cursors that are declared, opened, closed, and deallocated in the function. Only FETCH statements that assign values to local variables using the INTO clause are allowed; FETCH statements that return data to the client are not allowed.


INSERT, UPDATE, and DELETE statements modifying table variables local to the function.


EXECUTE statements calling an extended stored procedures.


  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: Вопрос по хранимой процедуре
Ответ #7 - 05. Августа 2009 :: 09:18
Печать  
Код
Выбрать все
CREATE FUNCTION [dbo].[Parents](@Child char(9),@number_table INT) 




Код
Выбрать все
if @number_table = 1 then
	  select ...
	  from table_1
	  where ...
    end if;
    if @number_table = 2 then
	  select ...
	  from table_2
	  where ...
    end if;
    if @number_table = 3 then
	  select ...
	  from table_3
	  where ...
    end if;
 

  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Вопрос по хранимой процедуре
Ответ #8 - 05. Августа 2009 :: 09:54
Печать  
ИМХО, лучше создать для каждого справочника отдельную процедуру, по типу dbo.ParentsXXX.
  
Наверх
 
IP записан
 
mrgreen
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 32
Зарегистрирован: 01. Августа 2009
Re: Вопрос по хранимой процедуре
Ответ #9 - 17. Августа 2009 :: 14:01
Печать  
Кто может помочь в другой функции - тоже справочник но должна возвращать 1 если есть такая группа у элемента и 0 если нет... возвращает почему-то 0 постоянно... будто условие не отрабатывает

Код
Выбрать все
CREATE FUNCTION INParent
(
	@NomID varchar(9),@ParentID varchar(9)
)
RETURNS int
AS
BEGIN
	-- Declare the return variable here
	DECLARE @ParentID_N varchar(9),@ParentID_T varchar(9), @res int
	SET @res = 0

	WHILE @NomID <> '     0   '
		BEGIN
			SELECT @NomID = PARENTID FROM  SC282 WHERE ID = @NomID
			IF 	@NomID = @ParentID
				SET @res = 1
			END

	RETURN @res

END 



а сам вызов

SELECT ID, dbo.INParent(ID,'   61Y   ') as P FROM  SC282

ИД код такой есть точно
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Вопрос по хранимой процедуре
Ответ #10 - 17. Августа 2009 :: 14:38
Печать  
может так. Вместо varchar(9) надо использовать char(9)
( на базе не проверял)

Код
Выбрать все
CREATE FUNCTION INParent
(
	@NomID char(9),@ParentID char(9)
)
RETURNS int
AS
BEGIN
	-- Declare the return variable here
	DECLARE @cur_id char(9)
	DECLARE @par_id char(9)

	select @cur_id = @NomID
	WHILE @cur_id <> '     0   '
	BEGIN
		 SELECT @par_id = PARENTID FROM  SC282 WHERE ID = @cur_id
		 IF 	par_id = @ParentID
		 BEGIN
				RETURN 1
		 END
		 select @cur_id = @par_id
	END

	RETURN 0

END

 

  
Наверх
 
IP записан
 
mrgreen
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 32
Зарегистрирован: 01. Августа 2009
Re: Вопрос по хранимой процедуре
Ответ #11 - 17. Августа 2009 :: 14:46
Печать  
а так работает Улыбка (par_id ток параметром сделать)

спасибо... а что ж у меня там не то

разобрался - из-за varchar... мой тоже работает тогда Печаль
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Вопрос по хранимой процедуре
Ответ #12 - 17. Августа 2009 :: 14:53
Печать  
mrgreen писал(а) 17. Августа 2009 :: 14:46:
а так работает Улыбка (par_id ток параметром сделать)

спасибо... а что ж у меня там не то

разобрался - из-за varchar... мой тоже работает тогда Печаль

ну лучше наверное все в отдельную ветку.
твою фразу про varchar я не понял.
Т.к. для внутри одного справочника 1с использует только char(9)
то и нужно использовать именно этот тип данных.
  
Наверх
 
IP записан
 
mrgreen
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 32
Зарегистрирован: 01. Августа 2009
Re: Вопрос по хранимой процедуре
Ответ #13 - 18. Августа 2009 :: 08:18
Печать  
Улыбка кстати можно перенести в фак... как проверить элемент на вхождение в группу "прямым" способом... было бы - мне б день тратить не пришлось (зато не узнал бы как хранимки делать)

кстати а вопрос ещё вдогонку... а как проверить при начале работы системы есть ли такая процедура/функция или нет

а то я сейчас постоянно DROP делаю а это ведь не есть корректно...
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Вопрос по хранимой процедуре
Ответ #14 - 18. Августа 2009 :: 18:50
Печать  
mrgreen писал(а) 18. Августа 2009 :: 08:18:
как проверить при начале работы системы есть ли такая процедура/функция или нет

Код
Выбрать все
if not exists(select name from sysobjects where name = 'MyFunc' and type = 'FN')
  select 0
else
  select 1

--или
if not exists(select name from sysobjects where name = 'MyProc' and type = 'P')
  select 0
else
  select 1

--или
if object_id('MyFunc') /*or MyProc*/ is null select 0 else select 1
 

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать