NULL和VARCHAR之间的SQL联合错误

Coo*_*ter 5 sql t-sql null sql-server-2005 sql-server-2008

我有两个相同列的视图.第一个视图中的一列是"动态"生成并设置为NULL,而另一个视图上的相同列的值存储为varchar.我有一个看起来像这样的存储过程:

ALTER PROCEDURE [dbo].[mi_GetLearners]  
(@centrename nvarchar(200))  
AS  

SELECT [centrename]  
      ,[Name]  
      ,[Username] --generated on the fly as NULL
FROM  [DB1].[dbo].[vw_Learners]  
WHERE [centrename] = @centrename  

UNION  

SELECT [centrename]  
      ,[Name]   
      ,[Username] --values stored as varchar   
FROM  [Linked_Server].[DB2].[dbo].[vw_Learners]  
WHERE [centrename] = @centrename 
Run Code Online (Sandbox Code Playgroud)

DB1位于SQL Server 2008 R2上
DB2位于SQL Server 2005上

当我运行存储过程时,我收到以下错误:

当将varchar值'someusername'转换为数据类型int时,消息245,级别16,状态1,行1转换失败.

为什么尝试将值转换为int数据类型,因为另一列设置为NULL?如果我不是从改变第二列NULL' '存储的过程正常工作......我真的很困惑,为什么一个联盟之间的varchar列,并NULL在SELECT语句生成列会抛出这样的错误...任何想法?

编辑:我正在寻找解释而不是解决方案......

编辑2:运行以下代码:

CREATE VIEW vw_myview
AS
SELECT NULL AS MyColumn

EXECUTE sp_help vw_myview
Run Code Online (Sandbox Code Playgroud)

返回:

    Type    Column_name
     int       MyColumn
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 6

问题是NULL(在一些摆动室内)每个数据类型的成员.

SELECT运行任何查询时,每列的内容必须是一种类型,并且只能是一种类型.当列中包含值的混合(包括NULLs)时,显然可以通过检查非NULL值的类型来确定类型,并且根据需要执行适当的转换.

但是,当所有行包含NULL特定列,并且NULL尚未转换为特定类型时,则没有要使用的类型信息.所以,SQL Server有点随意决定这个列的类型是什么int.

create view V1
as
    select 'abc' as Col1,null as Col2
go
create view V2
as
    select 'abc' as Col1,CAST(null as varchar(100)) as Col2
Run Code Online (Sandbox Code Playgroud)

V1有类型的列varchar(3)int.

V2有类型的列varchar(3)varchar(100).