SQL Server 函数在错误的列中返回数据

Posted

技术标签:

【中文标题】SQL Server 函数在错误的列中返回数据【英文标题】:SQL Server Function returning data in wrong column 【发布时间】:2017-03-02 14:30:49 【问题描述】:

我遇到了一个用户定义的函数 (dbo.AnnualMetrics_ByCat(@StartYear, @EndYear)),它接受年份范围参数并包含大约 5 个 CTE 与从中选择数据的查询链接在一起.该函数被编码为返回如下表:

MonthYear | CATID | Classification | GeneralClass | TotalUsedVolume | TotalUnusedVolume
--------- | ----- | -------------- | ------------ | --------------- | -----------------
2/1/2010  |  AGR  |  Agricultural  |  NON-RES     |  429.615        | 138.543

函数调用时...

SELECT * FROM dbo.AnnualMetrics_ByCat(2006,2015) OPTION(MAXRECURSION 200)

...它返回一个像这样的表(其中缺少“GeneralClass”列,列值向右移动等):

MonthYear | CATID | Classification | TotalUsedVolume | TotalUnusedVolume
--------- | ----- | -------------- | --------------- | -----------------
2/1/2010  |  AGR  |  Agricultural  |  NON-RES        |  429.615  

将查询语法剪切/粘贴到 SSMS 窗口并手动运行时,将返回正确的表结构和值。

我的问题是,有人知道是什么原因造成的吗?删除该函数并使用原始 CREATE 脚本重新创建它解决了该问题,但是我仍然对问题的根源感到好奇。

【问题讨论】:

检查return语句,看看你想要的所有列是否都在里面。 向我们展示函数。 您的函数是否引用了视图?该视图是否有选择 *?你的函数有选择 * 吗? @SeanLange 该函数不引用视图,但其中一个 CTE 由 Select * From dbo.myDatabaseTable 语句填充。 【参考方案1】:

试试这个:

USE master;
GO
CREATE DATABASE TestDB;
GO
USE TestDB;
GO
CREATE TABLE t(x INT, y INT,z INT);
INSERT INTO t VALUES(1,2,3),(4,5,6);
GO
CREATE VIEW dbo.vw AS SELECT * FROM t;
GO
SELECT * FROM dbo.vw; --everything fine here
GO
ALTER TABLE t ADD NewColumn VARCHAR(100) NOT NULL DEFAULT('blah');
GO
SELECT * FROM dbo.vw; --the new column doesn't show up???
GO
ALTER TABLE t DROP COLUMN y;
GO
SELECT * FROM dbo.vw; --huh?!?!
GO
USE master;
DROP DATABASE TestDb;

最终结果

x   y   z
1   3   blah
4   6   blah

为什么 y 和 z 中的 z 值,即 INT,突然变成“废话”了?

问题是SELECT *。如果没有特定的列列表,您的视图会一个接一个地选择现有的列,而无需查看...

您必须刷新/重新创建视图。

更新

这点我不清楚问题是SELECT *

我真正的意思是:这就是问题所在,使用列名而不是*

(谢谢本·J·博伊尔)

【讨论】:

或者在select语句中显式命名列。无论如何,这样做可能会更好,以便视图只返回它需要的数据。

以上是关于SQL Server 函数在错误的列中返回数据的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server UDF 的列别名错误

SQL Server 2008 - 返回连接条目和“无法绑定多部分标识符”错误的用户定义函数

SQL SERVER:选择不返回值的列

在 SQL Server 的列中删除尾随空格和更新

如何重命名SQL Server中计算列中引用的列?

SQL Server 日期查询,年月作为单独的列