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