2016-02-29 1 views
1

У меня есть очень большая таблица (более 100 полей), где мне нужно сравнить две записи. Для этого я решил использовать PIVOT. Записи будут выбраны пользователем (так что они будут динамическими), но пока я помещаю их как статические.Ошибка SQL-подстроки в инструкции PIVOT

My SQL выглядит следующим образом:

-- Where clause params 
DECLARE @whereClauseParam VARCHAR(MAX) = '[42] <> [600]' --<-- User will need to determine what the condition will be 

--Get the Fields required for the initial pivot 
DECLARE @Fields VARCHAR(MAX)= ''; 

SELECT @Fields+=QUOTENAME(t.name)+', ' 
FROM sys.columns AS t 
WHERE t.object_id = OBJECT_ID('tblSQLAdminInventory') 
    AND t.name <> 'TransID' 
    AND t.system_type_id = '60'; 
--36 
--48 
--52 
--56 
--60 
--61 
--62 
--104 
--106 
--127 
--165 
--167 
--231 
--239 


-- Get the KeyId's with alias added 
DECLARE @keyIDs VARCHAR(MAX)= ''; 

SELECT @keyIDs+=QUOTENAME(t.TransID)+' AS [KeyID_'+CAST(t.TransID AS VARCHAR(10))+'], ' 
FROM tblSQLAdminInventory AS t 
WHERE TransID IN ('42', '600'); 

-- Get the KeyId's without alias 
DECLARE @keyIDs1 VARCHAR(MAX)= ''; 

SELECT @keyIDs1+=QUOTENAME(t.TransID)+', ' 
FROM tblSQLAdminInventory AS t 
WHERE TransID IN ('42', '600'); 

--Generate Dynamic SQL 
DECLARE @SQL2 VARCHAR(MAX)= 'SELECT Value AS FieldName, '; 

PRINT @SQL2+SUBSTRING(@keyIDs, 1, LEN(@keyIDs)-1) 
PRINT @keyIDs 
PRINT LEN(@keyIDs) 

SELECT @SQL2+=SUBSTRING(@keyIDs, 1, LEN(@keyIDs)-1)+' 
FROM 
(SELECT TransID , Value , FieldName 
FROM 
    (SELECT TransID,'+SUBSTRING(@Fields, 1, LEN(@Fields)-1)+' 
    FROM tblSQLAdminInventory) p 
UNPIVOT 
    (FieldName FOR Value IN 
     ('+SUBSTRING(@Fields, 1, LEN(@Fields)-1)+') 
)AS unpvt) AS SourceTable 
PIVOT 
(
MAX(FieldName) 
FOR TransID IN ('+SUBSTRING(@keyIDs1, 1, LEN(@keyIDs1)-1)+') 
) AS PivotTable 
--WHERE '[email protected] 

PRINT(@SQL2); 
EXECUTE(@SQL2); 

В 3 ПРИНТ линии над моей PIVOT распечатке, как это:

SELECT Value AS FieldName, [42] AS [KeyID_42], [600] AS [KeyID_600] 
[42] AS [KeyID_42], [600] AS [KeyID_600], 
41 

Все выглядит хорошо. Но, есть ошибка в моем PIVOT:

Msg 537, Level 16, State 5, Line 49 
Invalid length parameter passed to the LEFT or SUBSTRING function. 
SELECT Value AS FieldName, 
Msg 102, Level 15, State 1, Line 1 
Incorrect syntax near ','. 

Может кто-нибудь сказать мне, почему мой оператор печати распознает все 3 названия полей, но мое PIVOT заявление не делает?

ВОПРОС БОНУСА: При фильтрации по t.system_type_id = '56' он возвращает данные. Для любой другой system_type_id я получаю ошибку и никаких записей не возвращаются.

EDIT

В соответствии с просьбой, вот SQL2, когда он работает без ошибок:

SELECT Value AS FieldName, [42] AS [KeyID_42], [600] AS [KeyID_600] 
FROM 
(SELECT TransID , Value , FieldName 
FROM 
    (SELECT TransID,[ErisaPlanEndsMM], [ErisaPlanEndsDD], [MLRAvgLivesNumber], [MLRAvgLivesRptYear] 
    FROM tblSQLAdminInventory) p 
UNPIVOT 
    (FieldName FOR Value IN 
     ([ErisaPlanEndsMM], [ErisaPlanEndsDD], [MLRAvgLivesNumber], [MLRAvgLivesRptYear]) 
)AS unpvt) AS SourceTable 
PIVOT 
(
MAX(FieldName) 
FOR TransID IN ([42], [600]) 
) AS PivotTable 
--WHERE [42] <> [600] 
+0

Можете вы добавить результаты print @ SQL2? –

+0

Я решил попытаться разделить его на system_type_id, потому что я продолжал получать ошибки, что поля были не одинаковыми. Не уверен, что я напал на это правильно, но это все, что я мог придумать. –

ответ

1

Не уверен, если это решит все ваши проблемы, но вы можете использовать это, чтобы создать свой @keyIds и устранить потребность в Substring()

-- Get the KeyId's with alias added 
DECLARE @keyIDs VARCHAR(MAX),  
     @keyIDs1 VARCHAR(MAX); 

SELECT @keyIDs = COALESCE(@keyIDs + ',','') + QUOTENAME(t.TransID) + ' AS [KeyID_' + CAST(t.TransID AS VARCHAR(10)) + ']', 
     @keyIDs1 = COALESCE(@keyIDs1 + ',','') + QUOTENAME(t.TransID) 
FROM tblSQLAdminInventory AS t 
WHERE TransID IN ('42', '600'); 
+0

Это фиксировало два из них. : o) Еще одна проблема, о которой я расскажу в отдельном вопросе. Благодаря! –

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