6

I have some inline SQL Scripts (functions and stored procedures) generated with Entity framework , Code first approach.

Update-Database -Script -SourceMigration:0

With the above command I get SQL Script file that I execute on test or production.

However I cannot run the generated script because of the following error:

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

The script is generated as:

IF @CurrentMigration < '201410150019333_CreatefnGenerateRequestCode' BEGIN CREATE FUNCTION [dbo].[fnGenerateRequestCode] ( @userID varchar(max) )
RETURNS varchar(14)
as

How can I fix this?

Cœur
  • 37,241
  • 25
  • 195
  • 267
codebased
  • 6,945
  • 9
  • 50
  • 84

3 Answers3

4

You can avoid the

should be the first statement in a batch file

error without adding GO statements by putting the sql inside an EXEC command:

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

Reference:

https://stackoverflow.com/a/20352867/150342

Community
  • 1
  • 1
Colin
  • 22,328
  • 17
  • 103
  • 197
2

You have to generate your code and execute it as dynamic 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
SubqueryCrunch
  • 1,325
  • 11
  • 17
0

You need to execute the previous statements, to the CREATE FUNCTION, on a first EXEC statement and then run the CREATE FUNCTION into another EXEC statement.

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
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99