powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вычисляемые поля в процедуре
10 сообщений из 10, страница 1 из 1
Вычисляемые поля в процедуре
    #32004047
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые господа. Помогите "чайнику".
Имеется таблица:

CREATE TABLE #Probe (number int, factor numeric (19,4), formula varchar(100))

number; factor ;formula
------; ------- ;-----
1; 0.2 ;number*factor
212; 100 ;nuumber/factor
75; 428 ;number+factor

Необходимо получить в результате запроса (процедуры)

number; factor ;formula ;rez
------; ------- ;---------------- ;---
1; 0.2 ;number*factor ;0.2
212; 100 ;number/factor ;21200
75; 425 ;number+factor ;500

Формула вычисления может быть любая.
Как это сделать?
Заранее благодарен

P.S. Мои извинения за форматирование таблицы ";"
А как сделать это по-человечески? В Help не нашел.
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004058
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как по-человечески не знаю, но можно сделать примерно так:

во-первых надо добавить какой-нибудь ключ(id)
потом делаешь в цикле для каждой записи(в данном случае можно использовать и курсор) такой вызов

select @s='update probe set rez='+formula+' where id='+@id)
exec(@s)

где @id - это id текущей записи

суть надеюсь понятна


С приветом Сергей
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004156
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Колоссальное СПАСИБО, Сергей!!!
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004501
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2SergSuper and All interested: Сергей, еще раз Большое спасибо, суть ухватил, но видимо не до конца.
В первоначальном примере столбец rez непосредственно в таблице отсутствует. Он должен возникает при выполнении процедуры, результат которой и возвращается в клиентское приложение. Но здесь у меня возникли некоторые проблемы.
В следующей процедуре сначала создается временная таблица (вроде, как ее заполнили пользователи), а потом, проходясь по ней курсором – обновляется столбец rez, как Вы и рекомендовали (если я правильно понял ):
CREATE procedure numbers_vr (@i bigint=1, @n bigint =10)
as
begin
-- создаем таблицу и заполняем ее чем попало (типа эта таблица у нас была)
create table #numbers (id int identity(1, 1) not null ,n1 bigint, n2 numeric(19,4), formula varchar(100), rez numeric(19,4))
declare @z varchar (1), @zn int
while @i<=@n
begin
-- ceiling(rand()*10/2.5) используется только для генерации целого "случайного" числа от 1 до 4
-- и конвертации 1-4 в знаки арифметических действий
set @zn=convert(int, ceiling(rand()*10/2.5))
set @z =case @zn when 1 then '+' when 2 then '-' when 3 then '*' when 4 then '/' end
--заполнение таблицы чем попало
insert #numbers values (ceiling(rand()*100), @zn, 'n1'+@z+'n2', null)
set @i =@i+1
end
select * from #numbers
-- Обновляем поле rez таблицы #numbers (хотя это можно было сделать и в предыдущем цикле)
declare result cursor for select * from #numbers
declare @s varchar(100), @id int ,@n1 bigint, @n2 numeric(19,4), @formula varchar(100), @rez numeric(19,4)
open result
while @@fetch_status=0
begin
fetch next from result into @id , @n1 , @n2 , @formula , @rez
-- как и рекомендовалось
set @s='update #numbers set rez=' +@formula+' where id='+convert(varchar, @id )
exec(@s)
end
close result
deallocate result
select * from #numbers
end

Все работает и все замечательно, НО при попытке заменить временную таблицу переменной типа table (вместо create table #numbers – declare @numbers table и везде по тексту @numbers вместо #numbers), результат получается несколько иным. А именно: exec(@s) после set @s='update @numbers set rez=' +@formula+' where id='+convert(varchar, @id) выдает ошибку «…Must declare the variable '@numbers '…». Оно и понятно, exec выполняется, как отдельная процедура, а таблица @numbers в ней, само собой, не определена.
1) Как выходить из этого положения?
2) В данном случае exec(@s) возвращает единственное значение. Как в таких случаях (не только в данном контексте) его можно использовать в дальнейшем? Например, для присвоения этого значения некоторой переменной.
Заранее благодарю.
Андрей. andrewrw.fm.com.ua или tand@svitonlane.com
P
.S Процедура работает (по крайней мере, у меня работала )
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004507
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Andrew

Увы, если б я знал как... А я знаю не больше вашего.
Максимум что можно сделать - вместо временной таблицы использовать постоянную, одно из полей которой будет spid - идентификатор коннекшена. Будет несколько побыстрее(не надо создавать и уничтожать каждый раз таблицу), но суть та же.

С приветом Сергей
sergsuper@mail.ru
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004519
Michael Hopgarden
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
declare @s as varchar(64)
select @s = 'declare @i as int; select @i = 1; select @i'
exec(@s)
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004526
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Michael Hopgarden
Ну а теперь напишите такую процедуру "calc", которая бы работала так:

declare @o int
exec calc '2+2', @o out

select @o

а выдать селект должен 4, т.е. результат 2+2.

То что Вы написали можно было написать проще: select @s='select 1'
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004537
GreenSunrise
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного к вопросу об exec(@s). Есть такая полезная sp - sp_executesql. Очень полезна, когда надо выполнить сформированную на ходу строку SQL с параметрами. Например,

declare @par1 int
declare @s nvarchar(1000)

set @par1 = 20

set @s = 'select * from peoples where age = @par1'
exec (@s)

В этом случае будет выдано сообщение 'Must declare the variable '@par1'.'
А вот если написать exec sp_executesql @s, N'@par1 int', @par1 = @par1
то все прекрасно выполнится. Кстати, параметры для sp_executesql можно объявлять выходными, что в некоторых ситуациях просто необходимо. Может быть, в вашем случае при замене #numbers на @numbers как раз и поможет такой подход ?
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004543
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2GreenSunrise
Большое человеческое спасибо! Таки можно это дело написать без временных таблиц!


create procedure s_calc_str -- считает выражение
@str varchar(300), -- само выражение
@m TBabki out, -- сколько получилось
@show int=0 -- если 1 - вывести селектом
AS
BEGIN
declare @s nvarchar(400)
select @s='set @m=('+@str+')'
exec sp_executesql @s, N'@m TBabki out', @m out
if @show=1 select @m 'val'
END

Жаль функцию нельзя сделать
...
Рейтинг: 0 / 0
Вычисляемые поля в процедуре
    #32004560
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2GreenSunrise: Множество огромных человеческих спасибо!
Это здорово облегчит мне жизнь.
2ALL: Но вдогонку позвольте еще пару дурацких вопросов:
Функцию из этого будет сделать невозможно because "Invalid use of 'EXECUTE' within a function."
1) Как в таком случае передать набор данных (переменная типа table) из процедуры в другую для дальнейшей обработки? Курсором? - так он там не нужен. Через объявленную глобальную переменную? - так их нету.
2) Почему не работает следующий код:
create procedure MyProc @n int for output , @t1 table (id int, d int) for output
as ...
"Incorrect syntax near the keyword 'table'."
Т.е все типы переменных(в том числе курсоры)FOR OUTPUT можно, а table нельзя.
(похоже я опять не дочитал BOL )
Всем спасибо!
Andrew
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вычисляемые поля в процедуре
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]