Execute Query Inside Column From CTE - sql

I have a CTE table which returns dynamic SQL.
Here is my CTE query:
DECLARE #Qry VARCHAR(MAX)
;WITH CTE AS
(
SELECT
Qry = 'UPDATE data_'+ REPLACE(mrp.father_uid, '-', '_')+' SET done = 2 WHERE uid = '''+ CAST(mrp.uid AS VARCHAR(250)) + ''''
FROM
[4928_MyProcessDB].dbo.main_result_process mrp WITH (NOLOCK)
INNER JOIN
[4928_MyProcessDB].dbo.main_result_process_part mrpp WITH (NOLOCK) ON mrp.uid = mrpp.process_uid
)
SELECT *
FROM CTE
which returns:
I want to execute each row on the CTE table. How can I do that?

With just a couple of tweaks
DECLARE #Qry VARCHAR(MAX) = ''
;WITH CTE AS
(
SELECT
Qry = ';UPDATE data_'+ REPLACE(mrp.father_uid, '-', '_')+' SET done = 2 WHERE uid = '''+ CAST(mrp.uid AS VARCHAR(250)) + ''''
FROM
[4928_MyProcessDB].dbo.main_result_process mrp WITH (NOLOCK)
INNER JOIN
[4928_MyProcessDB].dbo.main_result_process_part mrpp WITH (NOLOCK) ON mrp.uid = mrpp.process_uid
)
SELECT #Qry = #Qry + Qry
FROM CTE
Exec(#Qry)

Related

Passing parameter to stored procedure using dynamic SQL into pivot data

I am trying to pass a parameter into Stored procedure to filter data in my select statement but when i use the parameter it gives error Message: Invalid column name 'SessionId2075'. when I use static value in the where clause the procedure works fine. Can you please give me fix the issue. I checked all the previous answers and could not find the working solution.
Alter PROCEDURE [dbo].GetPivotFeeReport
(
#SessionId varchar(50)
)
as
begin
DECLARE #SQL as VARCHAR(MAX)
DECLARE #Columns as VARCHAR(MAX)
SET NOCOUNT ON;
SELECT #Columns =
COALESCE(#Columns + ', ','') + QUOTENAME(GroupHeaderValue)
FROM
(SELECT DISTINCT mgh.GroupHeaderValue
FROM StudentFeeDetail sf
INNER JOIN MasterGroupHeaderValue mgh
ON mgh.GroupHeaderValueId = sf.FeeForId
) AS B
ORDER BY B.GroupHeaderValue
SET #SQL = 'SELECT ClassName,' + #Columns + ',TOTAL
FROM
(
SELECT
distinct mc.className,
sf.FinalAmount,
mgh.GroupHeaderValue,
Sum (isnull(sf.FinalAmount,0)) over (partition by ClassName) AS TOTAL
--0 AS TOTAL
FROM StudentFeeDetail sf
INNER JOIN StudentAdmission sa
ON sa.AdmissionId = sf.AdmissionId
INNER JOIN MasterClass mc
ON mc.ClassId = sa.ClassId
INNER JOIN MasterGroupHeaderValue mgh
ON mgh.GroupHeaderValueId = sf.FeeForId
WHERE sa.SessionId = (' + #SessionId + ') -- this is where I am trying to use the parameter when used static value like this ''SessionId2075'' the procedure works fine
and sf.FeeAmt >0
GROUP BY className, FinalAmount, GroupHeaderValue
) as PivotData
PIVOT
(
sum(FinalAmount)
FOR GroupHeaderValue IN (' + #Columns + ')
) AS PivotResult
ORDER BY (ClassName)
'
EXEC ( #sql)
end

Is there a better way to find a specific value in dynamic query?

I'm trying to find out is there a value in a dynamic query, at the moment I'm using this solution:
DECLARE
#SQL NVARCHAR(MAX)
, #ISLN NUMERIC(9,0) = '967272'
SET #SQL =
'SELECT *
FROM ITEM
LEFT OUTER JOIN SHIPMENT_DETAIL
ON ITEM.ITEM = SHIPMENT_DETAIL.ITEM
AND (SHIPMENT_DETAIL.COMPANY = ITEM.COMPANY OR ITEM.COMPANY IS NULL)
WHERE (SHIPMENT_DETAIL.warehouse = N''SH'' )
ORDER BY ITEM.ITEM ASC'
SELECT #SQL = STUFF (
#SQL
, 8
, 1
, 'INTERNAL_SHIPMENT_LINE_NUM'
)
DECLARE #TEMP TABLE (ISLN NUMERIC(9,0))
INSERT INTO #TEMP (ISLN)
EXEC SP_SQLEXEC #SQL
IF EXISTS (SELECT 1 FROM #TEMP WHERE ISLN = #ISLN)
SELECT 1
ELSE
SELECT 0
Dynamic SQL is generated by other software, so I cannot change the input data.
Is there a better way to find specific value in specific column of a dynamic query?
Try this, hope it will help you:
DECLARE
#SQL NVARCHAR(MAX)
, #ISLN NUMERIC(9,0) = '967272'
SET #SQL =
'SELECT *
FROM ITEM
LEFT OUTER JOIN SHIPMENT_DETAIL
ON ITEM.ITEM = SHIPMENT_DETAIL.ITEM
AND (SHIPMENT_DETAIL.COMPANY = ITEM.COMPANY OR ITEM.COMPANY IS NULL)
WHERE (SHIPMENT_DETAIL.warehouse = N''SH'' )
ORDER BY ITEM.ITEM ASC'
SELECT #SQL = 'if exists (' + STUFF (
#SQL
, charindex('where', #sql) + 6
, 0
, 'INTERNAL_SHIPMENT_LINE_NUM = ' + cast(#isln as varchar(20)) + ' and '
) + ') select 1 else select 0;';
EXEC SP_SQLEXEC #SQL;

Select Into #Temp not working with a PIVOT

I've got this dynamically created mess that essentially takes all fields in a table and compares two records against each other:
DECLARE #ID1 AS VarChar(3)
DECLARE #ID2 AS VarChar(3)
Set #ID1 = '42'
Set #ID2 = '600'
-- Where clause params
DECLARE #whereClauseParam VARCHAR(MAX) = '['+#ID1+'] <> ['+#ID2+']'
--***************************************--
--******** tblSQLAdminInventory ********--
--***************************************--
--Get the Fields required for the initial pivot
DECLARE #AIFields VARCHAR(MAX)= '';
DECLARE #AIFields2 VARCHAR(MAX)= '';
SELECT #AIFields+=QUOTENAME(t.name)+', '
FROM sys.columns AS t
WHERE t.object_id = OBJECT_ID('tblSQLAdminInventory')
AND t.name <> 'TransID'
--AND t.system_type_id = '56';
SELECT #AIFields2+='Convert(VarChar(250), '+QUOTENAME(t.name)+') AS '+ QUOTENAME(t.name) +', '
FROM sys.columns AS t
WHERE t.object_id = OBJECT_ID('tblSQLAdminInventory')
AND t.name <> 'TransID'
--AND t.system_type_id = '56';
--56 (Int)
--61 (DateTime)
--104 (Bit)
--167 (VarChar)
--231 (NVarChar)
-- Get the KeyId's with alias added
DECLARE #AIkeyIDs VARCHAR(MAX),
#AIkeyIDs1 VARCHAR(MAX);
SELECT #AIkeyIDs = COALESCE(#AIkeyIDs + ',','') + QUOTENAME(t.TransID) + ' AS [KeyID_' + CAST(t.TransID AS VARCHAR(10)) + ']',
#AIkeyIDs1 = COALESCE(#AIkeyIDs1 + ',','') + QUOTENAME(t.TransID)
FROM tblSQLAdminInventory AS t
WHERE TransID IN (#ID1, #ID2);
--Generate Dynamic SQL
DECLARE #AISQL2 VARCHAR(MAX)= 'SELECT Value AS FieldName, ';
SELECT #AISQL2+=#AIkeyIDs+'
FROM
(SELECT TransID, Value, FieldName
FROM
(SELECT TransID, '+SUBSTRING(#AIFields2, 1, LEN(#AIFields2)-1)+'
FROM tblSQLAdminInventory) p
UNPIVOT
(FieldName FOR Value IN
('+SUBSTRING(#AIFields, 1, LEN(#AIFields)-1)+')
)AS unpvt) AS SourceTable
PIVOT
(
MAX(FieldName)
FOR TransID IN ('+#AIkeyIDs1+')
) AS PivotTable
WHERE '+#whereClauseParam
EXECUTE(#AISQL2);
The problem is, it won't seem to let me put the results in a temp table. I tried using this code but it keeps telling me the #Temp1 object doesn't exist:
SELECT #AISQL2+=#AIkeyIDs+'
INTO #Temp1
FROM
(SELECT TransID, Value, FieldName
FROM
(SELECT TransID, '+SUBSTRING(#AIFields2, 1, LEN(#AIFields2)-1)+'
FROM tblSQLAdminInventory) p
UNPIVOT
(FieldName FOR Value IN
('+SUBSTRING(#AIFields, 1, LEN(#AIFields)-1)+')
)AS unpvt) AS SourceTable
PIVOT
(
MAX(FieldName)
FOR TransID IN ('+#AIkeyIDs1+')
) AS PivotTable
WHERE '+#whereClauseParam
What am I doing wrong?
You're using dynamic SQL. The EXECUTE statement starts a whole new scope and that temporary table isn't available in that scope.
There are several work-arounds, like using a permanent table that you clear out or using a global temporary table, but they all have their own pitfalls.

Dynamic Pivot with CTE

I was trying to create a Common Table Express(CTE) to store some data that I need which requires a bunch of inner join. Then, I would like to pivot the result using dynamic pivot columns. I wrote the query below but I'm getting the error
"Common table expression defined but not used."
How can I create a pivot query base on a CTE? By the way, I can do it without the CTE but I would like to know if I can do it with CTE.
DECLARE #cols nvarchar(max)
DECLARE #sql nvarchar(max)
SELECT #cols = isnull(#cols + ', ', '') + '[' + Convert(varchar(max),T.CostCenterNumber) + ']' FROM (SELECT distinct CostCenterNumber FROM CostCenters) as T
;With PivotData as (
SELECT B.[Year], C.CostCenterNumber, C.CostCenterName, E.[Description] as GLClass, D.Code, D.[GLDescription], A.Total
From GeneralLedgers A inner join
Years B on A.YearID = B.ID
inner join CostCenters C on
A.CostCenterID = C.ID
inner join GLCodes D on
A.GLCodeID = D.ID inner join
GLClassificationTypes E on
D.GLClassificationTypeID = E.ID)
SELECT #sql = '
Select *
From(
SELECT [Year], CostCenterNumber, GLClass, Code, GLDescription, Total
FROM PivotData) as T
PIVOT
(
Max(Total)
for [CostCenterNumber] in (' + #cols + ')
)) as P'
EXEC(#sql)
Here is how you can do it. I have written the logic inside the query
DECLARE
#cols nvarchar(max),
#stmt nvarchar(max)
SELECT #cols = isnull(#cols + ', ', '') + '[' + Convert(nvarchar(max),T.CostCenterNumber)+ ']'
FROM (SELECT distinct CostCenterNumber FROM CostCenters) as T
SELECT #stmt = '
-- Your CTE goes here
;WITH CTE AS
(
SELECT [Year], E.[Description] as GLClass, Code,
GLDescription, CostCenterNumber, Total
FROM GeneralLedgers A inner join
Years B on A.YearID = B.ID inner join
GLCodes C on A.GLCodeID = C.ID inner join
CostCenters D on A.CostCenterID = D.ID inner join
GLClassificationTypes E on C.GLClassificationTypeID = E.ID
)
-- Pivoted reuslt
SELECT * FROM
(
-- Here you select the data from CTE
SELECT *
FROM CTE
)as T
PIVOT
(
max(T.Total)
for T.[CostCenterNumber] in (' + #cols + ')
) as P'
exec sp_executesql #stmt = #stmt

Enclosing Select to use PIVOT

I have tried a couple of combinations to wrap the last select to use PIVOT with its result
This is the code
DECLARE #cols VARCHAR(1000)
DECLARE #sqlquery VARCHAR(2000)
SELECT #cols = STUFF(( SELECT distinct ',' + QuoteName(idIndice)
FROM tgpwebged.dbo.sistema_Indexacao as a FOR XML PATH('')
), 1, 1, '')
SET #sqlquery = 'WITH TempTable AS
(
select distinct a.id, b.idIndice, b.valor
from tgpwebged.dbo.sistema_Documentos as a
join tgpwebged.dbo.sistema_Indexacao as b on a.id = b.idDocumento
join tgpwebged.dbo.sistema_DocType as c on a.idDocType = c.id
join tgpwebged.dbo.sistema_DocType_Index as d on c.id = d.docTypeId
where d.docTypeId = 40
and (b.idIndice = 11 AND b.valor = ''11111111'' OR b.idIndice = 12 AND b.valor = ''11111'' )
)
SELECT * FROM TempTable t1
WHERE ((select count(*)
from TempTable t2
where t1.id = t2.id AND t1.valor != t2.valor) = 1)base
PIVOT
(
Max(valor)
FOR [idIndice] IN (' + #cols + ')
) AS finalpivot'
EXECUTE ( #sqlquery )
This of course will not work so do I need to enclose parentheses or somenthing like that to get it done???
Try replace EXECUTE ( #sqlquery ) on EXEC #sqlquery
more info about EXECUTE statement