我使用EAV模式在单个表(Entries
)中存储任意数据。 Data
存储为nvarchar
,并通过PropertyID
链接目标数据类型。现在我想创建一个使用pivot重构数据的视图,但是我无法动态地将Data
转换为其预期的数据类型。执行下面的查询,我收到错误#8114 error converting data type nvarchar to float
。
这基本上是我的数据库结构:
EntryID | PropertyID | Data (nvarchar)
----------------------------
1 | 1 | 1
2 | 2 | abc
3 | 3 | 2.0
....
PropertyID | PropertyName | TypeID
------------------------------------
1 | intProp | 1
2 | strProp | 2
3 | fltProp | 3
....
TypeID | TypeName
-----------------
1 | int
2 | string
3 | float
4 | bool
5 | datetime
....
这是查询:
SELECT [intProp], [strProp], [fltProp]
FROM
(
SELECT e.EntryID, p.PropertyName,
CASE
WHEN t.TypeName = 'int' THEN
CAST(e.data as int)
WHEN t.TypeName = 'float' THEN
CAST(e.data as float)
WHEN t.TypeName = 'string' THEN
e.data
END as converted
FROM
Entries e
INNER JOIN Properties p ON e.PropertyID = p.PropertyID
INNER JOIN Types t ON p.TypeID = t.TypeID
) as t1
PIVOT
(
MAX(converted)
FOR PropertyName IN ( [intProp], [strProp], [fltProp])
) as piv
显然CASE
语句是问题所在,但是如何将查询转换为动态转换为正确的数据类型?
答案 0 :(得分:1)
根据我之前的评论,我尝试创建一个可能对您有帮助的SQL脚本:
DECLARE @colsConversion as NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SELECT @colsConversion = STUFF((SELECT ',CAST('+QuoteName(p.PropertyName)+' as '+t.TypeName+') as '+QuoteName(p.PropertyName)
FROM Properties p
INNER JOIN Types t ON p.TypeID = t.TypeID
GROUP BY p.PropertyName, t.TypeName
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,1,'')
SET @query = 'SELECT ' + @colsConversion +'
FROM
(
SELECT e.EntryID,p.PropertyName,t.TypeName
,e.Data
FROM Entries e
INNER JOIN Properties p ON e.PropertyID = p.PropertyID
INNER JOIN Types t ON p.TypeID = t.TypeID
)AS T1
PIVOT
(
MAX(Data)
FOR PropertyName in ([intProp],[strProp],[fltProp])
)as piv'
exec sp_executesql @query