problem in executing dynamic query using pivot with syntax error Incorrect syntax near ' + ' - sql

I want to Create a query with dynamic query and in this query i use concat some cells , when use concat like 'N'subject:' + ' ' + ContentProductionTitle' i get syntax error
error : Incorrect syntax near ' + '.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.KeyWordTitle)
FROM TBL_CU_ContentProduction_KeyWord c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + ' from
(
select
isnull((select N'subject:' + ' ' + ContentProductionTitle
from Tbl_Cu_ContentProductionCalendar
where ContentProductionCalendarID = a.ActionSubjectId ),'')
+' ' +
isnull((select top 1 N'author:'+ p.FullName + ' ' from users.TblProfiles as p
where p.UserId= a.ActionUserID ),'') +' ' +
isnull((select top 1 N'edit bye:' + ' ' + p.FullName from users.TblProfiles as p
where p.UserId= a.CheckAgain ) ,'') as title
, a.ActionDateTo
, k.KeyWordTitle
from TBL_CU_ContentProduction_KeyWord as k
inner join Tbl_CU_ContentProduction as cp
on k.ContentGUID = cp.ContentGUID
inner join Tbl_Cu_ActionContentProduction as a
on a.ContentGUID = cp.ContentGUID
) x
pivot
(
max(ActionDateTo)
for KeyWordTitle in (' + #cols + ')
) p '
execute(#query)

you need to escape single quote inside your query string with '':
set #query = 'SELECT ' + #cols + ' from
(
select
isnull((select N''subject:'' + '' '' + ContentProductionTitle
from Tbl_Cu_ContentProductionCalendar
where ContentProductionCalendarID = a.ActionSubjectId ),'''')
+'' '' +
isnull((select top 1 N''author:''+ p.FullName + '' '' from users.TblProfiles as p
where p.UserId= a.ActionUserID ),'''') +'' '' +
isnull((select top 1 N''edit bye:'' + '' '' + p.FullName from users.TblProfiles as p
where p.UserId= a.CheckAgain ) ,'''') as title
, a.ActionDateTo
, k.KeyWordTitle
from TBL_CU_ContentProduction_KeyWord as k
inner join Tbl_CU_ContentProduction as cp
on k.ContentGUID = cp.ContentGUID
inner join Tbl_Cu_ActionContentProduction as a
on a.ContentGUID = cp.ContentGUID
) x
pivot
(
max(ActionDateTo)
for KeyWordTitle in (' + #cols + ')
) p '

Related

Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'SELECT'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '.'

I try to run 2 dynamic SQL, but I have an error that the syntax is incorrect. When I make a select for every parameter that I declare, there is no problem. But when I try to execute the string I have these erroes. Any help?
Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'SELECT'. Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '.'
--declare Variablen für die Prozedur
declare #DispoColumn nvarchar(max) = (select STRING_AGG(col.name, ', ') within group (order by col.column_id)
FROM sys.objects obj
JOIN sys.columns col on col.object_id = obj.object_id
JOIN sys.types typ ON col.user_type_id=typ.user_type_id
Where obj.name = #Tabelle and obj.schema_id = 5
GROUP BY obj.name);
declare #ID nvarchar(150) = (select MAX(CASE WHEN col.column_id = 1 THEN col.name ELSE NULL END)
FROM sys.objects obj
JOIN sys.columns col on col.object_id = obj.object_id
JOIN sys.types typ ON col.user_type_id=typ.user_type_id
Where obj.name = #Tabelle and obj.schema_id = 5
GROUP BY obj.name);
declare #EFREdispoUpdate nvarchar(max)
declare #ESFdispoUpdate nvarchar(max)
declare #ESFdispoInsert nvarchar(max)
declare #EFREdispoInsert nvarchar(max)
--Update der Tabellen
set #ESFdispoUpdate = 'UPDATE ESF.' + #Tabelle + ' SET GUELTIG_BIS = GETDATE() WHERE GUELTIG_BIS = ''9999-12-31'' AND ' + #ID + ' IN ( SELECT '
+ #ID + 'FROM ( SELECT ' +#DispoColumn + ' FROM ESF.' + #Tabelle + ' WHERE GUELTIG_BIS = ''9999-12-31''' + ' EXCEPT SELECT ' + #DispoColumn + ' SF.' + #Tabelle + ') as alt );'
+ ' UPDATE DISPO.T_TABELLEN SET ANZ_GEANDERT = (SELECT COUNT(*) FROM ESF.'+#Tabelle + ' WHERE GUELTIG_BIS = GETDATE())'
+ 'WHERE SCH_NAME = ''ESF'' AND TAB_NAME = ''' +#Tabelle + ''';';
set #EFREdispoUpdate = 'UPDATE EFRE.' + #Tabelle + ' SET GUELTIG_BIS = GETDATE() WHERE GUELTIG_BIS = ''9999-12-31'' AND ' + #ID + ' IN ( SELECT '
+ #ID + 'FROM ( SELECT ' +#DispoColumn + ' FROM EFRE.' + #Tabelle + ' WHERE GUELTIG_BIS = ''9999-12-31''' + ' EXCEPT SELECT ' + #DispoColumn + ' SF.' + #Tabelle + ') as alt );'
+ ' UPDATE DISPO.T_TABELLEN SET ANZ_GEANDERT = (SELECT COUNT(*) FROM EFRE.'+#Tabelle + ' WHERE GUELTIG_BIS = GETDATE())'
+ 'WHERE SCH_NAME = ''EFRE'' AND TAB_NAME = ''' +#Tabelle + ''';';
EXEC sp_executesql #ESFdispoUpdate;
EXEC sp_executesql #EFREdispoUpdate;
Your issue is because on the second line of your set statements, you forgot a space before FROM
Other minor changes
Added brackets to column names just in case column has special character like a space
Removed unnecessary GROUP BY clauses in subqueries
Changed second subquery from CASE WHEN to WHERE so it's more intuitive
DECLARE #Tabelle NVARCHAR(100) = 'YourTable'
declare #DispoColumn nvarchar(max) = (select STRING_AGG(QUOTENAME(col.name), ', ') within group (order by col.column_id)
FROM sys.objects obj
JOIN sys.columns col on col.object_id = obj.object_id
WHERE obj.name = #Tabelle AND obj.schema_id = 5
);
declare #ID nvarchar(150) = (SELECT QUOTENAME(col.name)
FROM sys.objects obj
JOIN sys.columns col on col.object_id = obj.object_id
Where obj.name = #Tabelle AND obj.schema_id = 5
AND col.column_id = 1
);
select #DispoColumn,#ID
declare #EFREdispoUpdate nvarchar(max)
,#ESFdispoUpdate nvarchar(max)
,#ESFdispoInsert nvarchar(max)
,#EFREdispoInsert nvarchar(max)
set #ESFdispoUpdate = 'UPDATE ESF.' + #Tabelle + ' SET GUELTIG_BIS = GETDATE() WHERE GUELTIG_BIS = ''9999-12-31'' AND ' + #ID + ' IN ( SELECT '
+ #ID + ' FROM ( SELECT ' +#DispoColumn + ' FROM ESF.' + #Tabelle + ' WHERE GUELTIG_BIS = ''9999-12-31''' + ' EXCEPT SELECT ' + #DispoColumn + ' SF.' + #Tabelle + ') as alt );'
+ ' UPDATE DISPO.T_TABELLEN SET ANZ_GEANDERT = (SELECT COUNT(*) FROM ESF.'+#Tabelle + ' WHERE GUELTIG_BIS = GETDATE())'
+ 'WHERE SCH_NAME = ''ESF'' AND TAB_NAME = ''' +#Tabelle + ''';';
set #EFREdispoUpdate = 'UPDATE EFRE.' + #Tabelle + ' SET GUELTIG_BIS = GETDATE() WHERE GUELTIG_BIS = ''9999-12-31'' AND ' + #ID + ' IN ( SELECT '
+ #ID + ' FROM ( SELECT ' +#DispoColumn + ' FROM EFRE.' + #Tabelle + ' WHERE GUELTIG_BIS = ''9999-12-31''' + ' EXCEPT SELECT ' + #DispoColumn + ' SF.' + #Tabelle + ') as alt );'
+ ' UPDATE DISPO.T_TABELLEN SET ANZ_GEANDERT = (SELECT COUNT(*) FROM EFRE.'+#Tabelle + ' WHERE GUELTIG_BIS = GETDATE())'
+ 'WHERE SCH_NAME = ''EFRE'' AND TAB_NAME = ''' +#Tabelle + ''';';
/*Use for debugging*/
SELECT #ESFdispoUpdate
SELECT #EFREdispoUpdate

When make concatenation sql string query , error has occurred because single quote

SET #InventoryQuery = N'SELECT * FROM
(
SELECT Inven.Inventory_ID As ID,Inven.Inventory_ID As Number, Inventory_Date As ActionDate, ''Inventory'' AS [ActionType], IsNull(Sum(Product_Qty),0) Product_Qty, P.Product_Desc_ENG + '' ('' + P.Product_Weight + '')'' Product_Desc_ENG
FROM CRM.Product P
INNER JOIN [crm].[InventoryDetail] InvenDet ON P.Product_ID = InvenDet.Product_ID
INNER JOIN [crm].[Inventory] Inven ON Inven.Inventory_ID = InvenDet.Inventory_ID
WHERE Inven.Customer_Id = ' + CAST(#CustomerID AS VARCHAR(10)) +
' AND ( Inven.Inventory_Date BETWEEN ' + CONVERT(VARCHAR(20), #StartDate, 121) + '
AND ' + CONVERT(VARCHAR(20), #EndDate, 121) + ' ) GROUP BY Inven.Inventory_ID, Inventory_Date,P.Product_Desc_ENG,P.Product_Weight
) y
pivot
(
sum(Product_Qty)
for Product_Desc_ENG in (' + #cols + N')
) p2 '

SQL PIVOT does not recognize a table

I'm creating a pivot table but this error appears: Message 1087, level 15, state 2, line 6
Declare the table variable "#TABELLA_personale".
the #TABELLA_personale has been declared and works, so I don't understand what the problem is.
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET
#columns = N'';
SELECT
#columns += N', p.' + QUOTENAME((cast(IDUTENTE AS VARCHAR(MAX)) + ' ' + NOME + ' ' + COGNOME + ' ' + (ISNULL (LIVELLO, ''))))
FROM
(
SELECT
p.IDUTENTE,
p.NOME,
p.COGNOME,
p.LIVELLO
FROM
#TABELLA_personale AS p
INNER JOIN
#TABELLA_completa AS o
ON p.IDUTENTE = o.ID
GROUP BY
p.IDUTENTE,
P.NOME,
P.COGNOME,
P.LIVELLO
)
AS x;
SET
#sql = N'
SELECT
' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT
p.NOME,
o.ORELAVORATE
FROM
#TABELLA_personale AS p
INNER JOIN
#TABELLA_completa AS o ONp.IDUTENTE = o.ID
)
AS j PIVOT ( MAX(ORELAVORARE) FOR NOME IN
(
'
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '') + ')) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;

SQL join data row by level

I have table like this
level|value
1 |ABC
1 |XYZ
1 |QWER
2 |1234
2 |7360
3 |zxcv
3 |0001
How can I join each value on level 1 to all level below? Like:
ABC-1234-zxcv
ABC-1234-0001
ABC-7360-zxcv
...
It the number of levels is not fixed:
Declare #select varchar(max) = 'SELECT ',
#from varchar(max) = 'FROM ',
#where varchar(max) = 'WHERE ',
#query varchar(max)= '';
SELECT #select = #select + 't' + cast([level] as varchar(max)) + '.[value]+''-''+',
#from = #from + 'yourTable t' + cast([level] as varchar(max)) + ',',
#where = #where + 't' + cast([level] as varchar(max)) + '.[level] = ' + cast([level] as varchar(max)) + ' AND '
FROM yourTable
GROUP BY [level]
Set #query = SUBSTRING(#select, 1, len(#select) - 5) + ' ' +
SUBSTRING(#from, 1, len(#from) - 1) + ' ' +
SUBSTRING(#where, 1, len(#where) - 4) + ' ORDER BY 1'
EXEC(#query)
If you have always 3 levels, you can do it like this:
select
d1.value + '-' + d2.value + '-' + d3.value
from
data d1
cross join data d2
cross join data d3
where
d1.level = 1 and
d2.level = 2 and
d3.level = 3
order by
1
If the number of levels isn’t fixed, then you'll probably have to use a recursive CTE

Including WHERE clause in Dynamic Pivot

I have created a working dynamic pivot.
DECLARE
#AttributeNames as NVARCHAR(MAX),
#SQL as NVARCHAR(MAX);
DECLARE
#AssetGroup as NVARCHAR(MAX) = 'Water',
#AssetType as NVARCHAR(MAX)= 'Water Meters',
#RecStatus as NVARCHAR(MAX) = 'I';
SET #AttributeNames = STUFF(
(SELECT N',' + QUOTENAME(AttributeName) AS [text()]
FROM (SELECT DISTINCT G1_ATTRIBUTE_NAME as AttributeName
FROM dbo.GASSET_MASTER INNER JOIN
dbo.GASSET_ATTRIBUTE ON dbo.GASSET_MASTER.SERV_PROV_CODE = dbo.GASSET_ATTRIBUTE.SERV_PROV_CODE AND
dbo.GASSET_MASTER.G1_ASSET_SEQ_NBR = dbo.GASSET_ATTRIBUTE.G1_ASSET_SEQ_NBR
--WHERE (dbo.GASSET_MASTER.G1_ASSET_GROUP = ''' + #AssetGroup + ''') AND (dbo.GASSET_MASTER.G1_ASSET_TYPE = ''' + #AssetType + ''')
) AS AttributeName
ORDER BY AttributeName
FOR XML PATH('')),
1,1, N'');
SET #SQL = N'SELECT *
FROM (SELECT dbo.GASSET_MASTER.G1_ASSET_ID, dbo.GASSET_ATTRIBUTE.G1_ASSET_SEQ_NBR, dbo.GASSET_ATTRIBUTE.G1_ATTRIBUTE_NAME,
dbo.GASSET_ATTRIBUTE.G1_ATTRIBUTE_VALUE, dbo.GASSET_MASTER.G1_ASSET_GROUP, dbo.GASSET_MASTER.G1_ASSET_TYPE,
dbo.GASSET_MASTER.G1_ASSET_STATUS, dbo.GASSET_MASTER.REC_STATUS
FROM dbo.GASSET_MASTER LEFT OUTER JOIN
dbo.GASSET_ATTRIBUTE ON dbo.GASSET_MASTER.SERV_PROV_CODE = dbo.GASSET_ATTRIBUTE.SERV_PROV_CODE AND
dbo.GASSET_MASTER.G1_ASSET_SEQ_NBR = dbo.GASSET_ATTRIBUTE.G1_ASSET_SEQ_NBR
WHERE (dbo.GASSET_MASTER.G1_ASSET_GROUP = ''' + #AssetGroup + ''') AND (dbo.GASSET_MASTER.G1_ASSET_TYPE = ''' + #AssetType + ''') AND (dbo.GASSET_MASTER.REC_STATUS <> ''' + #RecStatus + ''')) as SState
PIVOT (
MAX(G1_ATTRIBUTE_VALUE)
FOR G1_ATTRIBUTE_NAME IN(' + #AttributeNames + N')) AS P;';
Print #SQL
This code results in what i believe to be a properly formatted pivot. But when I attempt to use the commented out WHERE clause when building the columns no records are returned and no errors are received.
--WHERE (dbo.GASSET_MASTER.G1_ASSET_GROUP = ''' + #AssetGroup + ''') AND (dbo.GASSET_MASTER.G1_ASSET_TYPE = ''' + #AssetType + ''')
I have attempted to change the WHERE clause in a number of different ways with no success. Any ideas how I could do this differently?
Change the commented line to this one:
WHERE (dbo.GASSET_MASTER.G1_ASSET_GROUP = #AssetGroup ) AND (dbo.GASSET_MASTER.G1_ASSET_TYPE = #AssetType )
Explanation: The first query is not a dynamic query, you do not need to embed '