找不到数据类型 - 错误仅发生在较大的脚本中
Cannot find data type - error occurs only inside larger script
我正在创建一个 UDF。
该函数成功创建 ONLY 如果我 运行 CREATE FUNCTION
块本身。
如果我在更大的 "complete" 数据库创建脚本中包含 CREATE FUNCTION
块,我会收到一条奇怪的错误消息,指出使用了无效的数据类型。
(请参阅下面的代码块和错误屏幕截图。)
USE MyDB
、SET ANSI_NULLS
和 SET QUOTED_IDENTIFIER
在这两种情况下是相同的,没有任何效果。
这很奇怪,因为 UDTT 是在数据库创建脚本中更早创建的,没有错误。我可以在 SSMS 中看到 UDTT,所以它显然存在......
如果我 re-run 完整的数据库创建脚本,我显然会收到一堆关于重新创建已经存在的对象的消息 - 我忽略了这些消息,因为这是预期的。
但是后来我得到了这个错误,导致这个特定的函数创建失败,这阻止了它之后的许多其他对象创建。
如果我删除数据库,re-run 完整的数据库创建脚本,我在这一行之前没有收到任何错误,我仍然收到关于此数据类型无效的相同错误消息。
可能是什么原因造成的?
如果我想 "repair" 完整的数据库创建脚本,我应该从哪里开始?
USE MyDB
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[Test_FloatToNString] ( )
RETURNS @TestResults TABLE (
[Category] NVARCHAR ( MAX ) NOT NULL ,
[Example] NVARCHAR ( MAX ) NOT NULL ,
[Expected] NVARCHAR ( MAX ) NOT NULL ,
[Actual] NVARCHAR ( MAX ) NOT NULL ,
[CaseSensitive] BIT NOT NULL ,
[Tolerance] NVARCHAR ( MAX ) NOT NULL ,
[Difference] NVARCHAR ( MAX ) NOT NULL ,
[Passed] BIT NOT NULL ,
[Description] NVARCHAR ( MAX ) NOT NULL
)
AS BEGIN
DECLARE @testData [NStringTestData] ; /* Error here, see screenshot below */
INSERT INTO @testData /* etc. */
在完整的数据库创建脚本中,UDTT 如下所示:
USE MyDB
GO
/* ... */
CREATE TYPE [dbo].[NStringTestData] AS TABLE(
[Category] [nvarchar](max) NOT NULL,
[Example] [nvarchar](max) NOT NULL,
[Expected] [nvarchar](max) NOT NULL,
[Actual] [nvarchar](max) NOT NULL,
[CaseSensitive] [bit] NOT NULL,
[Tolerance] [int] NOT NULL,
[Description] [nvarchar](max) NOT NULL
)
GO
这不是一个好的答案,但这里...
为了调试它,我会在 SSMS 中加载完整的查询,并在顶部添加 BEGIN TRANSACTION
。在下一行输入 -- ROLLBACK
。当您的查询失败时,您可以回滚,并以最小的创伤结束回到干净状态(空数据库)。
基本上只是开始删除功能失败时不需要的内容。删除一些 DDL 语句,测试 运行ning 并边走边回滚事务,直到 运行s 没有错误。当它 运行 没有错误时,很可能是你删除的最后一段代码导致了你的问题。
如果您要删除多个 DDL 语句(我会这样做),此时您可以更细化。我的意思是,删除一大堆你的函数不依赖的东西,然后 运行 整个查询。如果可行,回滚,将该块添加回 (Undo/Ctrl Z),然后更精细地删除较小的块,一次一个,直到删除单个语句。
将其视为搜索。当删除单个 DDL 语句使您的查询正常工作时,您找到了罪魁祸首。你只需要找到那个声明。
通过足够多的来回检查,您应该能够识别导致问题的代码块,希望是单个 DDL 语句。如果不是很明显为什么那段代码让你感到悲伤,post 在这里或在一个新问题中,希望其他人会比我更有帮助。
user5151179 提供的调试方法post很有帮助。
这是 post-mortem,它可能会帮助其他人在类似情况下缩小问题范围。
此问题是由于在问题函数之前创建的包含本机编译 functions/procedures 的数据库脚本(不是 本机编译的,并且不引用任何本机已编译的模块)。
我仍然不知道为什么会发生这种情况,但是将几十个本机编译的函数移动到脚本中不同的 "location"(靠近底部,大多数重要的是在创建问题函数之后)完全解决了问题,无需修改任何函数或程序。
数据库中的每个对象都与之前完全相同,只是创建顺序不同。
这让我感到困惑,因为这些对象之间没有任何引用,这将要求它们以特定顺序创建 - 而错误本身只是一个数据类型错误,对于位于在我的脚本的最顶部,在数据库中的任何其他对象之前创建。
如果有人知道为什么 SQL 服务器对 在创建 本机编译的函数和过程时如此挑剔,请随时发表评论或 post另一个答案。
我正在创建一个 UDF。
该函数成功创建 ONLY 如果我 运行 CREATE FUNCTION
块本身。
如果我在更大的 "complete" 数据库创建脚本中包含 CREATE FUNCTION
块,我会收到一条奇怪的错误消息,指出使用了无效的数据类型。
(请参阅下面的代码块和错误屏幕截图。)
USE MyDB
、SET ANSI_NULLS
和 SET QUOTED_IDENTIFIER
在这两种情况下是相同的,没有任何效果。
这很奇怪,因为 UDTT 是在数据库创建脚本中更早创建的,没有错误。我可以在 SSMS 中看到 UDTT,所以它显然存在......
如果我 re-run 完整的数据库创建脚本,我显然会收到一堆关于重新创建已经存在的对象的消息 - 我忽略了这些消息,因为这是预期的。
但是后来我得到了这个错误,导致这个特定的函数创建失败,这阻止了它之后的许多其他对象创建。
如果我删除数据库,re-run 完整的数据库创建脚本,我在这一行之前没有收到任何错误,我仍然收到关于此数据类型无效的相同错误消息。
可能是什么原因造成的?
如果我想 "repair" 完整的数据库创建脚本,我应该从哪里开始?
USE MyDB
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[Test_FloatToNString] ( )
RETURNS @TestResults TABLE (
[Category] NVARCHAR ( MAX ) NOT NULL ,
[Example] NVARCHAR ( MAX ) NOT NULL ,
[Expected] NVARCHAR ( MAX ) NOT NULL ,
[Actual] NVARCHAR ( MAX ) NOT NULL ,
[CaseSensitive] BIT NOT NULL ,
[Tolerance] NVARCHAR ( MAX ) NOT NULL ,
[Difference] NVARCHAR ( MAX ) NOT NULL ,
[Passed] BIT NOT NULL ,
[Description] NVARCHAR ( MAX ) NOT NULL
)
AS BEGIN
DECLARE @testData [NStringTestData] ; /* Error here, see screenshot below */
INSERT INTO @testData /* etc. */
在完整的数据库创建脚本中,UDTT 如下所示:
USE MyDB
GO
/* ... */
CREATE TYPE [dbo].[NStringTestData] AS TABLE(
[Category] [nvarchar](max) NOT NULL,
[Example] [nvarchar](max) NOT NULL,
[Expected] [nvarchar](max) NOT NULL,
[Actual] [nvarchar](max) NOT NULL,
[CaseSensitive] [bit] NOT NULL,
[Tolerance] [int] NOT NULL,
[Description] [nvarchar](max) NOT NULL
)
GO
这不是一个好的答案,但这里...
为了调试它,我会在 SSMS 中加载完整的查询,并在顶部添加 BEGIN TRANSACTION
。在下一行输入 -- ROLLBACK
。当您的查询失败时,您可以回滚,并以最小的创伤结束回到干净状态(空数据库)。
基本上只是开始删除功能失败时不需要的内容。删除一些 DDL 语句,测试 运行ning 并边走边回滚事务,直到 运行s 没有错误。当它 运行 没有错误时,很可能是你删除的最后一段代码导致了你的问题。
如果您要删除多个 DDL 语句(我会这样做),此时您可以更细化。我的意思是,删除一大堆你的函数不依赖的东西,然后 运行 整个查询。如果可行,回滚,将该块添加回 (Undo/Ctrl Z),然后更精细地删除较小的块,一次一个,直到删除单个语句。
将其视为搜索。当删除单个 DDL 语句使您的查询正常工作时,您找到了罪魁祸首。你只需要找到那个声明。
通过足够多的来回检查,您应该能够识别导致问题的代码块,希望是单个 DDL 语句。如果不是很明显为什么那段代码让你感到悲伤,post 在这里或在一个新问题中,希望其他人会比我更有帮助。
user5151179 提供的调试方法post很有帮助。
这是 post-mortem,它可能会帮助其他人在类似情况下缩小问题范围。
此问题是由于在问题函数之前创建的包含本机编译 functions/procedures 的数据库脚本(不是 本机编译的,并且不引用任何本机已编译的模块)。
我仍然不知道为什么会发生这种情况,但是将几十个本机编译的函数移动到脚本中不同的 "location"(靠近底部,大多数重要的是在创建问题函数之后)完全解决了问题,无需修改任何函数或程序。
数据库中的每个对象都与之前完全相同,只是创建顺序不同。
这让我感到困惑,因为这些对象之间没有任何引用,这将要求它们以特定顺序创建 - 而错误本身只是一个数据类型错误,对于位于在我的脚本的最顶部,在数据库中的任何其他对象之前创建。
如果有人知道为什么 SQL 服务器对 在创建 本机编译的函数和过程时如此挑剔,请随时发表评论或 post另一个答案。