Evi*_*lDr 3 sql-server t-sql sql-server-2016
我知道之前已经问过同样的问题,但情况略有不同,我想更多地解释为什么它在我的上下文中失败,当(AFAIK)返回类型相同时。
过去,在我的数据库中,我使用基于 CLR 的表值函数将逗号分隔值拆分为包含整数列的表。
因为 SQL2016 引入了STRING_SPLIT,我需要换掉这个函数的 CLR 部分,并替换为原生的 TSQL 函数(因为我有数百个依赖这个函数的存储过程)。
如果我在 SSMS 中修改这个函数,我会看到:
ALTER FUNCTION [dbo].[e4fn_CreateIdTable](
@Ids [nvarchar](max),
@separator [nchar](1))
RETURNS TABLE (
[IdVal] [int] NULL
) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [ValueSplitter].[MyCompany.ValueSplitter].[SplitToIntegers]
Run Code Online (Sandbox Code Playgroud)
我希望我能够像这样改变它:
ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
@Ids [nvarchar](max),
@separator [nchar](1)
)
RETURNS TABLE
AS RETURN
(
SELECT
CAST(NULLIF(LTRIM(RTRIM(value)), '') AS int) AS IdVal
FROM
STRING_SPLIT(@Ids, @separator)
)
GO
Run Code Online (Sandbox Code Playgroud)
这返回了错误:
无法对“dbo.e4fn_CreateIdTable”执行更改,因为它是不兼容的对象类型。
我认为这是因为没有明确定义输出参数的表定义。所以,我这样重试:
ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
@Ids [nvarchar](max),
@separator [nchar](1)
)
RETURNS @tbl TABLE (
IdVal int
)
AS
BEGIN
INSERT INTO @tbl (
Idval
)
SELECT
CAST(NULLIF(LTRIM(RTRIM(value)), '') AS int)
FROM
STRING_SPLIT(@Ids, @separator);
RETURN;
END
GO
Run Code Online (Sandbox Code Playgroud)
再次出现相同的错误。
CLR TVF 是一种与 SQL TVF 根本不同的数据库对象类型,因此必须使用“DROP/CREATE”而不是ALTER更改定义。
CLR TVF 的sys.objects 中的类型是“FT”,而 SQL TVF(非内联)是“TF”。
| 归档时间: |
|
| 查看次数: |
8932 次 |
| 最近记录: |