Присвоение значений, возвращаемых функцией в Dynamic SQL

Я пытаюсь создать динамический SQL для назначения переменных со значениями из функции. Я пытаюсь сгенерировать SQL что-то вроде

Select @StartDate=@EID_Dept 
from dbo.WorkHistory(@today,@EID )

Функция возвращает дату (@EID_dept будет именем столбца, возвращаемого функцией), которую мне нужно присвоить @StartDate. А @EID_Dept создается путем объединения @EID и @dept.

Если я вручную напишу SQL, он будет выглядеть как

Select @StartDate = amaan_IT 
from dbo.WorkHistory('2016-10-10', amaan) 

Мой код ниже:

DECLARE @EID varchar(5), @StartDate VARCHAR(MAX), 
        @today DATETIME, @dept VARCHAR(10), @EID_dept varchar(20);

Select @today = SYSDATETIME()
Select @dept = dept from dbo.Dept(@EID)
Select @EID_Dept = CONCAT(@EID, @dept)

DECLARE @SQL Varchar(max);
SET @SQL = N'Select @StartDate = @EID_Dept 
             from dbo.PeriodHistory(@today, @EID)';

EXEC Sp_executesql
  @SQL,
  N'@StartDate VARCHAR(MAX) out,@EID_dept varchar(max),@today datetime,@EID Varchar',
  @StartDate out,
  @EID_Dept=@EID_Dept,
  @today=@today 

person Amaan Khan    schedule 25.10.2016    source источник
comment
Почему вы вообще используете динамический sql? Это ничего не делает для вас, кроме как усложняет задачу.   -  person Sean Lange    schedule 25.10.2016
comment
Вы не можете назначать имена объектов с помощью переменных, вам нужно будет использовать SET @SQL = CONCAT(N'SELECT @StartDate = ', @EID_Dept, ' FROM dbo.PeriodHistory(@Today, @EID);). Хотя это кажется далеким от идеала, я не уверен, что вы делаете это наилучшим образом.   -  person GarethD    schedule 25.10.2016
comment
EID будет меняться, и мне нужно объединить EID n Dept, чтобы получить данные из функции. Будет передан только EID, используя EID, мне нужно найти Dept, а затем объединить оба.   -  person Amaan Khan    schedule 25.10.2016


Ответы (1)


Я немного изменил ваш запрос. Надеюсь, это будет работать нормально:

DECLARE @EID nvarchar(5), 
        @StartDate nvarchar(MAX), 
        @today datetime = SYSDATETIME(), 
        @dept nvarchar(10), 
        @EID_dept nvarchar(20),
        @SQL nvarchar(max),
        @params nvarchar(max) = N'@StartDate nvarchar(MAX) out, @today datetime, @EID nvarchar(5)'

Select @dept = dept from dbo.Dept(@EID)
Select @EID_Dept = CONCAT(@EID, @dept)

SET @SQL = N'Select @StartDate = ' + QUOTENAME(@EID_dept) + ' from dbo.PeriodHistory(@today, @EID);';

EXEC sp_executesql  @SQL,
                    @params,
                    @StartDate = @StartDate out,
                    @today = @today,
                    @EID = @EID

SELECT @StartDate

Я использовал nvarchar(max) вместо @SQL (вы используете varchar, но добавляете N при присвоении значения переменной). sp_executesql ожидает nvarchar в части оператора

Строка Юникода, содержащая инструкцию или пакет Transact-SQL.

Все параметры я ставлю в переменную @params.

Как я понял, вам нужно получить другие столбцы на основе @EID_dept, поэтому я добавил QUOTENAME и использовал эту переменную напрямую в построении оператора SQL. Вы не можете отправить имя столбца как переменную.

person gofr1    schedule 26.10.2016