2013-04-16 3 views
0

У меня есть следующие столбцы в таблице: IdRec dataora aparat1 aparat2 .... aparat100 и следующий код в хранимой процедуре:динамический SQL (имя столбца переменной) с агрегатными функциями

ALTER PROCEDURE [dbo].[GetConsumRealElQRo] 
    @id_aparat int, 
    @datastart nvarchar(20), 
    @datastop nvarchar(20) 
AS 

declare 
@val_max real, 
@data_min datetime, 
@data_max datetime, 
@val_data_min real, 
@val_data_max real, 
@consum real 

BEGIN 
    SET NOCOUNT ON; 

if @id_aparat=1 
begin 
    select @val_max=max(aparat1),@data_min=min(dataora),@data_max=max(dataora) from table_name where (dataora between convert(datetime,@datastart,101) and convert(datetime,@datastop,101)) and aparat1 is not null 

    set @val_data_min=(
    select aparat1 from table_name 
    where [email protected]_min) 

    set @val_data_max=(
    select aparat1 from table_name 
    where [email protected]_max) 

    if @val_data_max<>@val_max 
    begin 
    set @[email protected][email protected][email protected]_data_max 
    end 
    else 
    begin 
    set @[email protected][email protected]_data_min 
    end 

    select @consum 
end 

if @id_aparat=2 
begin 
    select @val_max=max(aparat2),@data_min=min(dataora),@data_max=max(dataora) from table_name where (dataora between convert(datetime,@datastart,101) and convert(datetime,@datastop,101)) and aparat2 is not null 

    set @val_data_min=(
    select aparat2 from table_name 
    where [email protected]_min) 

    set @val_data_max=(
    select aparat2 from table_name 
    where [email protected]_max) 

    if @val_data_max<>@val_max 
    begin 
    set @[email protected][email protected][email protected]_data_max 
    end 
    else 
    begin 
    set @[email protected][email protected]_data_min 
    end 

    select @consum 
end 

и так далее , для каждого из этих 100 столбцов с именем aparat1, aparat2 ... aparat100.

Таким образом, процедура получает в качестве параметров целочисленный идентификатор столбца и две даты, выполняет некоторые вычисления и возвращает значение. Идентификатор столбца идентифицирует столбец и дает имя столбца (которое равно «aparat» + @id_aparat). Все, что я хочу, состоит в том, чтобы поместить блок вычислений в оператор for вместо того, чтобы копировать его сто раз для каждого значения @id_aparat. Это можно сделать с помощью динамического SQL?

EDIT: WORKING CODE Проблема решена. Для всех, кого это интересует, вот рабочий код:

USE [2013date] 
GO 
/****** Object: StoredProcedure [dbo].[GetConsumRealElQRo] Script Date: 4/18/2013 2:39:19 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[GetConsumRealElQRo] 
    @id_aparat int, 
    @datastart nvarchar(20), 
    @datastop nvarchar(20) 
AS 

declare 
@val_max real, 
@data_min datetime, 
@data_max datetime, 
@val_data_min real, 
@val_data_max real, 
@consum real 

BEGIN 
    SET NOCOUNT ON; 

declare 
@aparat as nvarchar(10), 
@tabel as nvarchar(50), 
@query as nvarchar(1000) 

set @aparat = 'aparat' + CONVERT(nvarchar(3),@id_aparat) 
set @tabel = 'table_name' 

set @query = 'select @val_max=max(' + @aparat + '),@data_min=min(dataora),@data_max=max(dataora) from ' + @tabel + ' 
    where (dataora between convert(datetime,''' + @datastart + ''',101) and convert(datetime,''' + @datastop + ''',101)) and ' + @aparat + ' is not null' 
--select @query 
exec sp_executesql @query, N'@val_max real output, @data_min datetime output, @data_max datetime output', @val_max output, @data_min output, @data_max output 
--select @val_max 
--select @data_min 
--select @data_max 

set @query = 'set @val_data_min=(select ' + @aparat + ' from ' + @tabel + ' where dataora=''' + Convert(nvarchar(30),@data_min,121) + ''')' 
--select @query 
exec sp_executesql @query, N'@val_data_min real output', @val_data_min output 
--select @val_data_min 

set @query = 'set @val_data_max=(select ' + @aparat + ' from ' + @tabel + ' where dataora=''' + Convert(nvarchar(30),@data_max,121) + ''')' 
--select @query 
exec sp_executesql @query, N'@val_data_max real output', @val_data_max output 
--select @val_data_max 

if @val_data_max<>@val_max 
    begin 
     set @[email protected][email protected][email protected]_data_max 
    end 
else 
    begin 
     set @[email protected][email protected]_data_min 
    end 

select @consum 

END 

ответ

1

У меня не было времени, чтобы попробовать этот вопрос, но ответ на ваш вопрос - да. Вы можете объявить переменную nvarchar, @ sql1, установить эту переменную как строку вашего запроса, а затем выполнить эту переменную. Итак, опять же, не тестируя этот запрос, мы здесь. SELECT в конце должен видеть запрос, который вы собираетесь выполнить, и exec (@ sql1) запускает запрос. Надеюсь, это будет иметь смысл и поможет вам!

declare @sql1 nvarchar(4000) 
set @sql1 = ' 
select @val_max=max(aparat' + convert(nvarchar(10),@id_aparat) + '),@data_min=min(dataora),@data_max=max(dataora) from table_name where (dataora between convert(datetime,@datastart,101) and convert(datetime,@datastop,101)) and aparat' +convert(nvarchar(10),@id_aparat)+' is not null 

    set @val_data_min=(
    select aparat' + convert(nvarchar(10),@id_aparat) + ' from table_name 
    where [email protected]_min) 

    set @val_data_max=(
    select aparat' + convert(nvarchar(10),@id_aparat) + ' from table_name 
    where [email protected]_max) 

    if @val_data_max<>@val_max 
    begin 
     set @[email protected][email protected][email protected]_data_max 
    end 
    else 
    begin 
     set @[email protected][email protected]_data_min 
    end 

select @consum' 

SELECT (@sql1) 
exec(@sql1) 
0

Пожалуйста, попробуйте следующее кодирование ....

ALTER PROCEDURE [dbo].[GetConsumRealElQRo] 
    @id_aparat int, 
    @datastart nvarchar(20), 
    @datastop nvarchar(20) 
AS 

declare 
@val_max real, 
@data_min datetime, 
@data_max datetime, 
@val_data_min real, 
@val_data_max real, 
@consum real 

BEGIN 

    SET NOCOUNT ON; 

    Declare @ExecutionString NVARCHAR(500) 

    Set @ExecutionString = ' 
    Select @val_max=max(aparat'+ Cast(@id_aparat AS Varchar) +'),@data_min=min(dataora),@data_max=max(dataora) from table_name where (dataora between convert(datetime,@datastart,101) and convert(datetime,@datastop,101)) and aparat1 is not null 

     set @val_data_min=(
     select aparat'+ Cast(@id_aparat AS Varchar) +' from table_name 
     where [email protected]_min) 

     set @val_data_max=(
     select aparat'+ Cast(@id_aparat AS Varchar) +' from table_name 
     where [email protected]_max) 

     if @val_data_max<>@val_max 
     begin 
      set @[email protected][email protected][email protected]_data_max 
     end 
     else 
     begin 
      set @[email protected][email protected]_data_min 
     end 

     Select @consum 
    ' 

    Exec SP_Executesql @ExecutionString, N'@id_aparat INT', @id_aparat 

    SET NOCOUNT OFF; 
Go 
+0

Ничего из этого не работает. – user2285985

+0

Получите таблицу образцов и данные. –

Смежные вопросы