列类型与unpivot列表中其他列类型冲突

导致问题原因可能是:转置列的字段长度不一致问题导致,如下例所示:

具体示例如下:

DECLARE @tmpTable TABLE (
NAME VARCHAR(30)
,address_desc VARCHAR(10)
,personal_desc VARCHAR(100)
)


INSERT INTO @tmpTable(NAME,address_desc,personal_desc)
SELECT 'jim','abc','test1'
UNION
SELECT 'tom','cccc','test2'


SELECT *
FROM @tmpTable --由于原始表中字段长途不一致导致错误
UNPIVOT (
paraval FOR para IN (NAME,address_desc,personal_desc)
) aa


执行结果:

消息 8167,级别 16,状态 1,第 15 行
列 "address_desc" 的类型与 UNPIVOT 列表中指定的其他列的类型冲突。


如果我做如下修改:

DECLARE @tmpTable TABLE (
NAME VARCHAR(30)
,address_desc VARCHAR(10)
,personal_desc VARCHAR(100)
)


INSERT INTO @tmpTable(NAME,address_desc,personal_desc)
SELECT 'jim','abc','test1'
UNION
SELECT 'tom','cccc','test2'


--将所有字段长度改为一致
SELECT *
FROM (
SELECT
CAST(t.NAME AS VARCHAR(100)) AS 'NAME'
,CAST(t.address_desc AS VARCHAR(100)) AS 'address_desc'
,CAST(t.personal_desc AS VARCHAR(100)) AS 'personal_desc'
FROM @tmpTable t
) cc
 UNPIVOT (
paraval FOR para IN (NAME,address_desc,personal_desc)
) aa


执行结果:

paraval para
jim NAME
abc address_desc
test1 personal_desc
tom NAME
cccc address_desc
test2 personal_desc


参考网址:

http://dba.stackexchange.com/questions/54353/why-does-sql-server-require-the-datatype-length-to-be-the-same-when-using-unpivo

When applying the UNPIVOT function to data that is not normalized, SQL Server requires that the datatype and length be the same. I understand why the datatype must be the same but why does UNPIVOT require the length to be the same?

Let's say that I have the following sample data that I need to unpivot:

CREATE TABLE People
(
    PersonId int, 
    Firstname varchar(50), 
    Lastname varchar(25)
)

INSERT INTO People VALUES (1, 'Jim', 'Smith');
INSERT INTO People VALUES (2, 'Jane', 'Jones');
INSERT INTO People VALUES (3, 'Bob', 'Unicorn');

If I attempt to UNPIVOT the Firstname and Lastname columns similar to:

select PersonId, ColumnName, Value  
from People
unpivot
(
  Value 
  FOR ColumnName in (FirstName, LastName)
) unpiv;

SQL Server generates the error:

Msg 8167, Level 16, State 1, Line 6

The type of column "Lastname" conflicts with the type of other columns specified in the UNPIVOT list.

In order to resolve the error, we must use a subquery to first cast the Lastname column to have the same length as Firstname:

select PersonId, ColumnName, Value  
from
(
  select personid, 
    firstname, 
    cast(lastname as varchar(50)) lastname
  from People
) d
unpivot
(
  Value FOR 
  ColumnName in (FirstName, LastName)
) unpiv;

See SQL Fiddle with Demo

Prior to UNPIVOT being introduced in SQL Server 2005, I would use a SELECT with UNION ALL to unpivot the firstname/lastname columns and the query would run without the need to convert the columns to the same length:

select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;

See SQL Fiddle with Demo.

We are also able to successfully unpivot the data using CROSS APPLY without having the same length on the datatype:

select PersonId, columnname, value
from People
cross apply
(
    select 'firstname', firstname union all
    select 'lastname', lastname
) c (columnname, value);

See SQL Fiddle with Demo.

I have read through MSDN but I didn't find anything explaining the reasoning for forcing the length on the datatype to be the same.

What is the logic behind requiring the same length when using UNPIVOT?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值