3

Я использую шаблон EAV для хранения произвольных данных в одной таблице (Entries). Data хранится как nvarchar и через PropertyID связан целевой тип данных. Теперь я хотел бы создать представление, чтобы реорганизовать данные с помощью шарнира, но у меня возникли проблемы с динамически отбрасывать 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 утверждение является проблемой, но как я могу преобразовать запрос динамически отбрасывать к правильному типу данных?

+1

Вы должны были бы сделать бросок после поворота, но вы не можете сделать это динамически. Вы можете сделать только CAST (piv. [IntProp] AS INT). Вы столкнулись с одной из причин, по которым «EAV» считается анти-шаблоном SQL. – GarethD

+0

Это может помочь решить проблему: kishang

ответ

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 
+0

Это работало для меня! Я пошел вперед и создал две переменные, чтобы сохранить динамические имена столбцов. Итак, наряду с '@ colsConversion', у меня также есть SELECT @cols = COALESCE (@cols + ',', '') + QUOTENAME (custom_data_name)', который я использую вместо оператора 'in' в' PIVOT' команда. Спасибо, что поделился! –

Смежные вопросы