"CREATE FUNCTION" должен быть первым оператором в пакете запроса. Entity Framework Code First

У меня есть несколько встроенных SQL-скриптов (функций и хранимых процедур), сгенерированных с помощью Entity Framework, Code сначала.

Update-Database -Script -SourceMigration: 0

С помощью приведенной выше команды я получаю файл сценария SQL, который я выполняю в тестовом или производственном режиме.

Однако я не могу запустить сгенерированный скрипт из-за следующей ошибки:

'CREATE FUNCTION' must be the first statement in a  query batch. 

Сценарий генерируется как:

IF @CurrentMigration<'201410150019333_CreatefnGenerateRequestCode' BEGIN CREATE FUNCTION [dbo]. [FnGenerateRequestCode] (@userID varchar (max))
ВОЗВРАЩАЕТСЯ varchar(14)
как

Как я могу это исправить?

2 ответа

Решение

Вы должны сгенерировать свой код и выполнить его как динамический SQL.

DECLARE @Sql NVARCHAR(MAX)
SET @Sql = 
'
IF OBJECT_ID(''fn_Test'') IS NOT NULL DROP FUNCTION fn_Test
GO

CREATE FUNCTION fn_Test(@a INT)
RETURNS INT
BEGIN
    RETURN @a
END
'
IF 1 = 1
BEGIN
    EXEC(@Sql)
END

Вы можете избежать

должен быть первым оператором в командном файле

ошибка без добавления операторов GO путем помещения sql в команду EXEC:

Sql(EXEC('BEGIN CREATE FUNCTION etc'))

Ссылка:

/questions/23443112/dobavlenie-operatorov-go-v-migratsii-entity-framework/23443133#23443133

Вам необходимо выполнить предыдущие операторы для CREATE FUNCTION в первом операторе EXEC, а затем выполнить CREATE FUNCTION в другом операторе EXEC.

DECLARE @query NVARCHAR(3000) = ''

SET @query += 'SET ANSI_NULLS ON' + CHAR(10) 

SET @query += 'SET QUOTED_IDENTIFIER ON' + CHAR(10) 

SET @query +=  'IF EXISTS (SELECT *
                           FROM   sys.objects
                           WHERE  object_id = OBJECT_ID(N''[dbo].[' + @DB_Name + '_InitCap]'')
                                  AND type IN ( N''FN'', N''IF'', N''TF'', N''FS'', N''FT'' ))
                  DROP FUNCTION [dbo].['+ @DB_Name + '_InitCap]' + CHAR(10)

EXEC sp_executesql @query

SET @query = 'CREATE FUNCTION [dbo].[' + @DB_Name + '_InitCap] ( @InputString varchar(4000) ) RETURNS VARCHAR(4000) AS' + CHAR(10)
....
....
EXEC sp_executesql @query