1

我有一个不寻常的情况 - 第一次!

我正在尝试在 Visual Studio 中为 SSDT 项目编写预部署脚本,该脚本将为迁移准备大量数据。TF在新版本的数据库中[MySchema].[MyFunc]有一个用户定义的表值函数(新版本中还有很多其他的对象,但我只需要使用这一个来帮助迁移。该函数对任何其他新的(或现有的)对象没有任何依赖关系,它是完全独立的。

我希望[MySchema].[MyFunc]作为预部署的一部分进行编译,以便我可以使用它。该函数位于.\MySchema\Functions\MyFunc.sql

我尝试了以下...

尝试 1

这失败了Incorrect syntax near CREATE(注意:CREATE是文件的第一行.\MySchema\Functions\MyFunc.sql):

IF object_id('[MySchema].[MyFunc]', 'TF') IS NULL
BEGIN
    :r .\MySchema\Functions\MyFunc.sql
END

尝试 2

这失败了Incorrect syntax near 'GO'and Incorrect syntax near ':' Expecting CONVERSATION

GO
IF object_id('[MySchema].[MyFunc]', 'TF') IS NULL
BEGIN
    :r .\MySchema\Functions\MyFunc.sql
    GO
END

尝试 3

将整个CREATE FUNCTION语句复制并粘贴到我的预部署脚本中:

CREATE FUNCTION [MySchema].[MyFunc]
(
    @p1 VARCHAR(255)
)
RETURNS @returntable TABLE
(
    some_col NVARCHAR(MAX)
)
AS
BEGIN
    -- some function code here
    RETURN
END

但这失败了CREATE FUNCTION must be the only statement in the batch。我尝试GO在此之前和之后插入,但我得到了与 ATTEMPT 2 相似的结果。我也尝试过使用;而不是GO.

尝试 4

我尝试使用iTVF,但没有帮助

尝试 5

我考虑了一会儿,将代码从我的函数中取出并在没有函数的情况下使用它......但我需要在迁移脚本中使用该代码大约 20 次。所以我拒绝了这个选项。每次都会产生不同的结果(由于参数的变化),所以我不能只是把它放在 CTE 或类似的东西中,然后每次都重新使用它。

请注意

答案应该是特定于 SSDT 项目的。这不是在 SSMS 中运行的代码。它位于 Visual Studio 中,将作为Publish进程的一部分运行。如果您不确定 SSDT 或预部署脚本是什么,请不要回答 :-) 任何不基于 SSDT 的答案都与这种情况无关。谢谢!

4

2 回答 2

1

如果您的目标是 SQL Server 2016 或更高版本,请想到两种可能的解决方案:

  1. 在包含您的功能代码之前分批尝试:
DROP FUNCTION IF EXISTS [MySchema].[MyFunc];
  1. 修改MyFunc.sql文件的内容,使其以:
CREATE OR ALTER FUNCTION [MySchema].[MyFunc]
...

参考:

于 2021-09-26T01:52:47.607 回答
0

您不能在 BEGIN/END 中使用 GO。我不明白为什么尝试 3 不起作用,很可能是因为您在同一脚本中拥有其他代码。通常您可以在预脚本中创建对象。根据 SQL Server 的版本,您可以使用IF EXISTS或更改该DROP函数的代码(如果它存在),然后始终CREATE使用它,而不是您尝试执行的相反方法。

另一种方法是将数据填充逻辑简单地放入预脚本本身。您可以执行以下操作:

IF NOT EXISTS (SELECT * FROM SomeTable)
BEGIN
  INSERT INTO SomeTable ...
END

在这种情况下,您将能够在不复制数据的情况下重新运行此脚本。

于 2021-09-27T07:59:20.670 回答