NULL和VARCHAR之间的SQL联合错误

时间:2012-07-11 11:27:44

标签: sql sql-server-2008 tsql sql-server-2005 null

我有两个相同列的视图。第一个视图中的一列是“动态”生成并设置为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 

DB1在SQL Server 2008 R2上 DB2在SQL Server 2005上

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

  

Msg 245,Level 16,State 1,Line 1转换时转换失败   varchar值'someusername'为数据类型int。

为什么尝试将值转换为int数据类型,因为另一列设置为NULL?如果我改为将第二列从NULL更改为' ',那么存储的proc工作正常...我真的很困惑为什么varchar列和{{1}之间的联合在select语句中生成的列会抛出这样的错误......任何想法?

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

编辑2:运行以下代码:

NULL

返回:

CREATE VIEW vw_myview
AS
SELECT NULL AS MyColumn

EXECUTE sp_help vw_myview

3 个答案:

答案 0 :(得分:5)

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

当运行任何SELECT查询时,每列的内容必须是一种类型,而且只能是一种类型。如果列中包含值的混合(包括NULL s),则显然可以通过检查非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

V1包含varchar(3)int类型的列。

V2包含varchar(3)varchar(100)类型的列。

答案 1 :(得分:4)

我希望字段的类型由union中的第一个SELECT确定。您可以尝试更改两个选择的顺序或更改为CAST(NULL AS VARCHAR(...))。

答案 2 :(得分:1)

我认为您需要转换为相同的数据类型:

---
AS  

SELECT [centrename]  
      ,[Name]  
      ,CAST(NULL AS VARCHAR(MAX)) AS [Username] 
FROM  [DB1].[dbo].[vw_Learners]  
WHERE [centrename] = @centrename  

UNION  
---