好的,还有另一个问题在forums.asp.net上没有得到任何好的答案,所以我想我会在这里试试。
我们的InstallShield代码有一个dll插件,可以通过ODBC读取和应用架构/数据升级脚本,作为安装过程的一部分。我不得不对我们的安装程序做一些工作,所以我将项目移动到另一台机器并开始工作,但发生了一件奇怪的事情 - 一个没有投诉的脚本突然开始抛出
“锚点与递归查询”TempCategoryValue“列'PathFromRoot'中的递归部分之间的类型不匹配
以前没有CTE上的错误。唯一改变的是我们的InstallShield插件的编译器版本。剧本旧;它已经运行了几年没有抱怨。该脚本正在处理旧的树表表示,尝试在每个节点添加和填充树继承的字符串表示。这个想法是你不需要很多外连接或递归CTE来告诉你在任何给定时间你在树中的位置,因为新的PathFromRoot列会告诉你。
但是将编译器从VS 2003更新到VS 2010突然改变了它看到CTE表达的方式。
我们的C ++应用程序浏览文本文件,并将GO语句之间的所有内容作为单独的命令运行,但是在同一个连接上。
我盯着查询了一会儿,却看不出为什么它不认为类型不匹配。 {Tree}中的[PathFromRoot]
被声明为varchar(900) not null
,CTE在递归子句中有明确的CONVERT(varchar(900),...)
。
任何人都知道为什么它会突然看到它们不同?
-- Table as it existed to start, before the script ran
CREATE TABLE [dbo].[TreeTable](
[TreeValueID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](128) NOT NULL,
[ParentValueID] [int] NULL
) ON [PRIMARY]
-- Add the PathFromRoot column to get a string representation of the tree hierarchy
ALTER TABLE TreeTable ADD PathFromRoot varchar(900) NOT NULL DEFAULT '.'
GO
-- Seed the new string column for the root tree values
UPDATE TreeTable SET PathFromRoot = CONVERT(nvarchar(25), TreeValueID) + '.'
WHERE ParentValueID IS NULL
GO
-- recursively update the rest of the PathFromRoot values
WITH TempTreeValue (ParentID, PathFromRoot, TreeValueID ) AS (
-- anchor member definition
SELECT ParentValueID, PathFromRoot, TreeValueID FROM TreeTable WHERE ParentValueID IS NULL
UNION ALL
-- recursive member definition
SELECT tv.ParentValueID, CONVERT(varchar(900), tv.PathFromRoot + CONVERT(varchar(25), tv.TreeValueID) + '.') as [PathFromRoot], tv.TreeValueID
FROM TreeTable tv
INNER JOIN TempTreeValue ttv ON tv.ParentValueID = ttv.TreeValueID
)
UPDATE TreeTable SET PathFromRoot = ttv.PathFromRoot FROM TreeTable t JOIN TempTreeValue ttv ON t.TreeValueID = ttv.TreeValueID
...