5

我有两个具有相同列的视图。第一个视图上的一列是“即时”生成的,并设置为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 上

当我运行存储过程时,出现以下错误:

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

为什么它试图将值转换为 int 数据类型,因为另一列设置为NULL?如果我改为将第二列从存储过程更改NULL' '正常工作......我真的很困惑为什么在选择语句中生成的varchar列和NULL列之间的联合会引发这样的错误......有什么想法吗?

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

编辑2:运行以下代码:

CREATE VIEW vw_myview
AS
SELECT NULL AS MyColumn

EXECUTE sp_help vw_myview

回报:

    Type    Column_name
     int       MyColumn
4

3 回答 3

7

问题是NULL(在一些回旋余地内)每种数据类型的成员。

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

于 2012-07-11T12:03:55.317 回答
4

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

于 2012-07-11T11:35:27.023 回答
1

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

---
AS  

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

UNION  
---
于 2012-07-11T11:33:27.420 回答