I want to get dynamic pivot result into temp table by which I can send it back to C# code using select query.
DECLARE #partymasterid bigint = 2;
DECLARE #cols AS NVARCHAR(MAX);
DECLARE #query AS NVARCHAR(MAX);
SELECT
#cols = STUFF((SELECT DISTINCT '[' + CAST(dbo.InventoryProductMaster.Name AS nvarchar(max)) + '],'
FROM dbo.InventoryBiltyMaster
INNER JOIN dbo.InventoryPartyProductPriceMaster ON dbo.InventoryBiltyMaster.InventoryPartyProductPriceMasterID = dbo.InventoryPartyProductPriceMaster.ID
INNER JOIN dbo.InventoryProductMaster ON dbo.InventoryPartyProductPriceMaster.InventoryProductMasterID = dbo.InventoryProductMaster.ID
WHERE dbo.InventoryBiltyMaster.PartyMasterID = #partymasterid
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 0, '');
SELECT #query =
'
SELECT
*
FROM
(SELECT
Count(dbo.InventoryBiltyMaster.ID) AS BiltyCount,
--dbo.InventoryBiltyMaster.InventoryProductMasterID,
--dbo.InventoryBiltyMaster.VehicleMasterID,
dbo.InventoryProductMaster.Name,
dbo.VehicleMaster.VehicleNumber
FROM
dbo.InventoryBiltyMaster
INNER JOIN dbo.InventoryPartyProductPriceMaster ON dbo.InventoryBiltyMaster.InventoryPartyProductPriceMasterID = dbo.InventoryPartyProductPriceMaster.ID
INNER JOIN dbo.InventoryProductMaster ON dbo.InventoryPartyProductPriceMaster.InventoryProductMasterID = dbo.InventoryProductMaster.ID
INNER JOIN dbo.VehicleMaster ON dbo.InventoryBiltyMaster.VehicleMasterID = dbo.VehicleMaster.ID
WHERE
dbo.InventoryBiltyMaster.PartyMasterID = ' + CAST(#partymasterid as nvarchar(50)) + '
GROUP BY
dbo.InventoryBiltyMaster.InventoryProductMasterID,
dbo.InventoryProductMaster.Name,
dbo.InventoryBiltyMaster.VehicleMasterID,
dbo.VehicleMaster.VehicleNumber
)
AS S
PIVOT
(
MAX(BiltyCount)
FOR [Name] IN (' + LEFT(#cols, LEN(#cols)-1) + ')
)AS pvt';
EXEC SP_EXECUTESQL #query
Here may be result have 3 column or 5 columns or 10-15 columns. it depends on the result of query. and this result i want on temp table for use more this data.
I want to use it in a stored procedure to send back result into ASP.NET MVC 5 with Entity Framework
You can't store inside a # (temp table) without defining it in the parent scope when using sp_executesql. In your case you have a dynamic pivot and you don't know what and how many columns are going to be there.
sp_executesql runs in a different session (sp_executesql creates its own session) and temp tables are session specific.
For your scenario you can use ## (global temp table). You can change your query like following.
SELECT #query =
'
SELECT
* into ##temp
FROM
(SELECT
Count(dbo.InventoryBiltyMaster.ID) AS BiltyCount,
--dbo.InventoryBiltyMaster.InventoryProductMasterID,
--dbo.InventoryBiltyMaster.VehicleMasterID,
dbo.InventoryProductMaster.Name,
dbo.VehicleMaster.VehicleNumber
FROM
dbo.InventoryBiltyMaster
INNER JOIN dbo.InventoryPartyProductPriceMaster ON dbo.InventoryBiltyMaster.InventoryPartyProductPriceMasterID = dbo.InventoryPartyProductPriceMaster.ID
INNER JOIN dbo.InventoryProductMaster ON dbo.InventoryPartyProductPriceMaster.InventoryProductMasterID = dbo.InventoryProductMaster.ID
INNER JOIN dbo.VehicleMaster ON dbo.InventoryBiltyMaster.VehicleMasterID = dbo.VehicleMaster.ID
WHERE
dbo.InventoryBiltyMaster.PartyMasterID = ' + CAST(#partymasterid as nvarchar(50)) + '
GROUP BY
dbo.InventoryBiltyMaster.InventoryProductMasterID,
dbo.InventoryProductMaster.Name,
dbo.InventoryBiltyMaster.VehicleMasterID,
dbo.VehicleMaster.VehicleNumber
)
AS S
PIVOT
(
MAX(BiltyCount)
FOR [Name] IN (' + LEFT(#cols, LEN(#cols)-1) + ')
)AS pvt';
EXEC SP_EXECUTESQL #query
--now you can use ##temp
Note: use of global temp table can lead to unpredictable behavior if it gets updated from multiple sessions, you may think of giving a unique name for each session.
Related
I have almost 1000 tables and most of them have a common column ItemNumber. How do I search across all the tables in the database for a value or list of values that exist in this common column, such as 350 or (350, 465)? The tables have different schemas.
Table A100
ItemNumber
Detail
230
Car
245
Plane
Table A1000
ItemNumber
ProductDescription
350
Pie
465
Cherry
This does not perform type checking, so you can get conversion errors if the target column is not the correct type. Also, this script uses LIKE, you would probably need to change that to a direct comparison.
SET NOCOUNT ON
DECLARE #ID NVARCHAR(100) = '2'
DECLARE #ColumnName NVARCHAR(100) ='UserID'
DECLARE #Sql NVARCHAR(MAX)=N'CREATE TABLE #TempResults(TableName NVARCHAR(50), ColumnName NVARCHAR(50), ItemCount INT)'
SELECT
#Sql = #Sql + N'INSERT INTO #TempResults SELECT * FROM (SELECT '''+ST.Name+''' AS TableName, '''+C.Name+''' AS ColumnName, COUNT(*) AS ItemCount FROM '+ST.Name+' WHERE '+C.Name+'='+#ID+') AS X WHERE ItemCount > 0 '
FROM
sys.columns C
INNER JOIN sys.tables ST ON C.object_id = ST.object_id
WHERE
C.Name LIKE '%'+#ColumnName+'%'
SET #Sql = #Sql + N'SELECT * FROM #TempResults'
exec sp_executesql #sql
You need to do this with dynamic SQL. You will need to query all 1000 tables, and make sure you are converting the values correctly if the columsn are different types.
You don't need a temp table for this, you can just script one giant UNION ALL query. You must make sure to quote all dynamic names correctly using QUOTENAME.
To be able to return data for multiple items, you should create a Table Valued Parameter, which you can pass in using sp_executesql.
First create a table type
CREATE TYPE dbo.IntList (Id int PRIMARY KEY);
Then you create a table variable containing them, and pass it in. You can also do this in a client application and pass in a TVP.
SET NOCOUNT ON;
DECLARE #Items dbo.IntList;
INSERT #Items (Id) VALUES(350),(465);
DECLARE #Sql nvarchar(max);
SELECT
#Sql = STRING_AGG(CONVERT(nvarchar(max), N'
SELECT
' + QUOTENAME(t.name, '''') + ' AS TableName,
t.ItemNumber,
COUNT(*) AS ItemCount
FROM ' + QUOTENAME(t.Name) + ' t
JOIN #items i ON i.Id = t.ItemNumber
GROUP BY
t.ItemNumber
HAVING COUNT(*) > 0
' ),
N'
UNION ALL
' )
FROM
sys.tables t
WHERE t.object_id IN (
SELECT c.object_id
FROM sys.columns c
WHERE
c.Name = 'ItemNumber'
);
PRINT #sql; -- your friend
EXEC sp_executesql
#sql,
N'#items dbo.IntList',
#items = #items READONLY;
If you don't need to know the count, and only want to know if a value exists, you can change the dynamic SQL to an EXISTS
....
SELECT
#Sql = STRING_AGG(CONVERT(nvarchar(max), N'
SELECT
' + QUOTENAME(t.name, '''') + ' AS TableName,
t.ItemNumber
FROM #items i
WHERE i.Id IN (
SELECT t.ItemNumber
FROM ' + QUOTENAME(t.Name) + ' t
)
' ),
N'
UNION ALL
' )
....
I need to be able to run a dynamic query within SQL Server, and store the results in an ADO recordset (in a VBA application). I've read that it's impossible to run dynamic SQL in a function (even a multi-statement function) - is this correct? I've also read that it's impossible to return a table variable from a stored procedure - is this also correct? If so, how do I do this?
The only ways I can think of involve:
having a permanent table, inserting into it with a stored procedure, and then running a function to get the results, or
querying the information I need to create the dynamic SQL into ADO, using VBA to generate the SQL string, and then querying that separately.
Neither of these are ideal. What I'd really like to have is this:
-- =============================================
-- Author: <snip>
-- Create date: 7/5/2022
-- Description: This function is for displaying details about report/query variant filters.
-- It takes the Report Variant ID, and returns all the display details from [list].[ReportAndQueryVariantDefaultFilterListInt]
-- =============================================
CREATE FUNCTION [dbo].[udf_Reports_DefaultFilterInfoForVariantID]
(
-- Add the parameters for the function here
#ReportVariantID int
)
RETURNS
#Tbl TABLE
(
-- Add the column definitions for the TABLE variable here
ListIDTypeID int
, PKID int
, [IDTypeDescription] varchar(50)
, ValueDisplay varchar(200)
)
AS
BEGIN
-- Fill the table variable with the rows for your result set
DECLARE #SQL nvarchar(max)
DECLARE #MainTblSchema varchar(8), #MainTblName varchar(100), #MainTblPKName varchar(50), #DisplayColumn varchar(50)
SET #SQL = 'INSERT INTO #Tbl (ListIDTypeID, PKID, IDTypeDescription, ValueDisplay) '
DECLARE Csr CURSOR LOCAL FAST_FORWARD FOR
SELECT DISTINCT tpk.[SchemaName], tpk.[TableName], tpk.[PKName], tpk.[DisplayColumnName]
FROM [list].[TablePrimaryKeys] tpk
INNER JOIN [list].[ReportAndQueryVariantDefaultFilterListInt] df ON tpk.ListIDTypeID = df.ListIDTypeID
WHERE df.ReportVariantID = #ReportVariantID
OPEN Csr
FETCH NEXT FROM Csr INTO #MainTblSchema, #MainTblName, #MainTblPKName, #DisplayColumn
WHILE ##fetch_status = 0
BEGIN
-- Quotename is needed if you ever use special characters
-- in table/column names. Spaces, reserved words etc.
-- Other changes add apostrophes at right places.
SET #SQL = CONCAT(#SQL, 'SELECT df.ListIDTypeID, df.PKID, tpk.IDTypeDescription, mt.' + QUOTENAME(#DisplayColumn) + '
FROM [list].[ReportAndQueryVariantDefaultFilterListInt] df
INNER JOIN [list].[TablePrimaryKeys] tpk ON df.ListIDTypeID = tpk.ListIDTypeID
INNER JOIN [' + QUOTENAME(#MainTblSchema) + '].[' + QUOTENAME(#MainTblName) + '] mt ON df.PKID = mt.' + QUOTENAME(#MainTblPKName) + '
WHERE df.ReportVariantID = #ReportVariantID ')
FETCH NEXT FROM Csr INTO #MainTblSchema, #MainTblName, #MainTblPKName, #DisplayColumn
IF ##FETCH_STATUS = 0
BEGIN
SET #SQL = CONCAT(#SQL, 'UNION ')
END
END
EXEC sp_executeSQL #SQL
CLOSE Csr
DEALLOCATE Csr
RETURN
END
Is there any way to accomplish this and return a recordset with a single ADO call?
You can't execute dynamic SQL in functions. But you can with stored procedures.
There are other issues also:
You have extra brackets before and after QUOTENAME (that function will add the brackets anyway.
You need to pass parameters properly in using sp_executesql. Outer parameters and variables do not exist in the dynamic scope automatically, you need to pass them.
Inserting into a table variable is not necessary, you can select straight out of the dynamic code.
You don't need the cursor, you can just use STRING_AGG
CREATE OR ALTER PROCEDURE [dbo].[udf_Reports_DefaultFilterInfoForVariantID]
#ReportVariantID int
AS
SET NOCOUNT, XACT_ABORT ON; -- always use these two
DECLARE #SQL nvarchar(max) = (
-- Quotename is needed if you ever use special characters
-- in table/column names. Spaces, reserved words etc.
-- Other changes add apostrophes at right places.
SELECT STRING_AGG(CAST('
SELECT
df.ListIDTypeID,
df.PKID,
tpk.IDTypeDescription,
mt.' + QUOTENAME(tpk.DisplayColumn) + ' AS ValueDisplay
FROM list.ReportAndQueryVariantDefaultFilterListInt df
INNER JOIN list.TablePrimaryKeys tpk ON df.ListIDTypeID = tpk.ListIDTypeID
INNER JOIN ' + QUOTENAME(tpk.SchemaName) + '.' + QUOTENAME(tpk.TableName) + ' mt ON df.PKID = mt.' + QUOTENAME(tpk.PKName) + '
WHERE df.ReportVariantID = #ReportVariantID
'
AS nvarchar(max)), 'UNION ALL ')
FROM list.TablePrimaryKeys] tpk
INNER JOIN list.ReportAndQueryVariantDefaultFilterListInt df ON tpk.ListIDTypeID = df.ListIDTypeID
WHERE df.ReportVariantID = #ReportVariantID
GROUP BY
tpk.SchemaName,
tpk.TableName,
tpk.PKName,
tpk.DisplayColumnName
);
PRINT #SQL; -- your friend;
EXEC sp_executesql #SQL,
N'#ReportVariantID int',
#ReportVariantID = #ReportVariantID;
There is a more efficient way of doing the dynamic query. You can union all the dynamic tables together first, then join ReportAndQueryVariantDefaultFilterListInt etc afterwards.
CREATE OR ALTER PROCEDURE [dbo].[udf_Reports_DefaultFilterInfoForVariantID]
#ReportVariantID int
AS
SET NOCOUNT, XACT_ABORT ON; -- always use these two
DECLARE #SQL nvarchar(max) = '
SELECT
df.ListIDTypeID,
df.PKID,
tpk.IDTypeDescription,
mt.ValueDisplay
FROM list.ReportAndQueryVariantDefaultFilterListInt df
INNER JOIN list.TablePrimaryKeys tpk ON df.ListIDTypeID = tpk.ListIDTypeID
INNER JOIN (
' + (
-- Quotename is needed if you ever use special characters
-- in table/column names. Spaces, reserved words etc.
-- Other changes add apostrophes at right places.
SELECT STRING_AGG(CAST('
SELECT mt.' + QUOTENAME(tpk.PKName) + ', mt.' + QUOTENAME(tpk.DisplayColumn) + '
FROM ' + QUOTENAME(tpk.SchemaName) + '.' + QUOTENAME(tpk.TableName) + ' mt
'
AS nvarchar(max)), 'UNION ALL ')
FROM list.TablePrimaryKeys] tpk
INNER JOIN list.ReportAndQueryVariantDefaultFilterListInt df ON tpk.ListIDTypeID = df.ListIDTypeID
WHERE df.ReportVariantID = #ReportVariantID
GROUP BY
tpk.SchemaName,
tpk.TableName,
tpk.PKName,
tpk.DisplayColumnName
) + '
) AS mt(PK, ValueDisplay) ON df.PKID = mt.PK
WHERE df.ReportVariantID = #ReportVariantID
';
PRINT #SQL; -- your friend;
EXEC sp_executesql #SQL,
N'#ReportVariantID int',
#ReportVariantID = #ReportVariantID;
This is just an FYI, in case it helps others. I'd marked Charlieface's answer as the best (thanks, Charlieface!), and it worked perfectly... as long as there was only one record returned in tpk. But if there was more than one type of primary key that needed to be included in the results, it gave a "subquery returned more than 1 value. this is not permitted" error. After some trial and error, here was the modified working code for setting up the value of #SQL (I'd changed a couple of table names in the interim, so the tables aren't exactly the same):
SET #SQL = ( SELECT STRING_AGG(CAST('
SELECT
df.ListIDTypeID,
df.PKID,
tpk.IDTypeDescription,
mt.' + QUOTENAME(tpk.DisplayColumnName) + ' AS ValueDisplay
FROM dbo.ReportAndQueryVariantFilterListInt df
INNER JOIN list.TablePrimaryKeys tpk ON df.ListIDTypeID = tpk.ListIDTypeID
INNER JOIN ' + QUOTENAME(tpk.SchemaName) + '.' + QUOTENAME(tpk.TableName) + ' mt ON df.PKID = mt.' + QUOTENAME(tpk.PKName) + '
WHERE df.ReportVariantID = #ReportVariantID AND df.ListIDTypeID = ' + CAST(df.ListIDTypeID AS nvarchar(10)) + '
'
AS nvarchar(max)), 'UNION ALL ')
FROM list.[TablePrimaryKeys] tpk
INNER JOIN (SELECT DISTINCT ListIDTypeID FROM dbo.ReportAndQueryVariantFilterListInt WHERE ReportVariantID = #ReportVariantID) df ON tpk.ListIDTypeID = df.ListIDTypeID
);
Could anyone have idea why my stored procedure encountered an error when I executed it?
I have tried to isolate in a simple select statement and supplying the value in where clause, it works fine. But when I put to stored procedure with a declared parameter, it won't work anymore.
This is the error after I execute the stored procedure:
Msg 137, Level 15, State 2, Line 30
Must declare the scalar variable "#BU".
See below for my stored procedure.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_Planning_GetMonthlyPivotX]
#BU char(7)
AS
BEGIN
DECLARE #PivotColumns AS NVARCHAR(MAX)
SELECT #PivotColumns = COALESCE(#PivotColumns + ',', '') + QUOTENAME([YEARMONTH])
FROM
(SELECT DISTINCT
CONVERT(CHAR(6), CAST([releaseddate] AS DATE), 112) AS [YEARMONTH]
FROM
[dbo].[ShopOrder]) AS PivotQuery
ORDER BY
[YEARMONTH]
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT *
FROM
(SELECT
a.[ItemCode], b.[Description],
B.[Catalog] as [BU], a.[WH],
f.[CustNo], f.[CustName],
b.[IsOutSource],
[dbo].[f_Routings_GetMCHr](a.[ItemCode]) as [Std.Time],
d.[Tonnage], d.[MachineNo],
d.[MachineNo] as [FixedMachine],
[dbo].[f_BOM_GetChildItem](a.ItemCode) as [ChildItem],
[dbo].[f_Item_GetItemDescription]([dbo].[f_BOM_GetChildItem](a.ItemCode)) as [ChildDescription],
[dbo].[f_BOM_GetChildQty](a.ItemCode,[dbo].[f_BOM_GetChildItem](a.ItemCode)) as [Usage],
e.[TRP],
CONVERT(char(6), cast([ReleasedDate] as date),112) as [YearMonthRel],
[dbo].[f_Inventory_GetTotalStock](b.[ItemCode]) as [Inventory],
b.[MinStockLvl] as [SafetyStock],
a.[RequiredQty] as [ShopOrderQty],
a.[FinishedQty] as [ActualQty],
g.[WorkTimeHr] as [AvailableTime]
FROM
[CPS].[dbo].[ShopOrder] AS a with(nolock)
LEFT OUTER JOIN
[CPS].[dbo].[items] AS b with(nolock) ON a.[ItemCode] = b.[ItemCode]
LEFT OUTER JOIN
[CPS].[dbo].[ItemByMachine] AS d with(nolock) ON a.[ItemCode] = d.[ItemCode]
LEFT OUTER JOIN
[CPS].[dbo].[MCTonnage] as e with(nolock) ON d.[Tonnage] = e.[Tonnage]
LEFT OUTER JOIN
[CPS].[dbo].[Customer] as f with(nolock) ON b.[CustNo] = f.[CustNo]
LEFT OUTER JOIN
[CPS].[dbo].[Machine] as g with(nolock) ON d.[MachineNo] = g.[MachineNo]
WHERE
b.[Catalog] = #BU) AS T
PIVOT
(
SUM([ShopOrderQty])
FOR [YearMonthRel] IN (' + #PivotColumns + ')
) p order by [Tonnage],[MachineNo],[ItemCode];'
Execute SP_EXECUTESQL #query
END
should be
WHERE b.[Catalog] = ''' + #BU + '''
and your select should be
SET #query = N'SELECT * FROM
as nvarchar
I am using SQL Server 2014 and I have the following T-SQL query which joins 2 tables:
SELECT a.*, b.* FROM TEMP a
INNER JOIN Extras b ON b.ResaID = a.ResaID
I would like to pull ALL the columns from TEMP and all the columns from "Extras" with the exception of the ResaID column as it is already included in a.* in the above query. Basically, I want to pull a.* + b.* (excluding b.ResaID).
I know I can write the query in the form:
Select a.*, b.column2, b.column3,...
but since b.* has got around 40 columns, is there a way to write the query in a more simplified way to exclude b.ResaID, rather than specify each of the columns in the "Extras" table?
Unfortunately, there is no such syntax. You could either use asterisks (*) and just ignore the duplicated column in your code, or explicitly list the columns you need.
You should create a view and select the columns you need from that view. Here is a script that will generate that view for you:
DECLARE #table1 nvarchar(20) = 'temp'
DECLARE #table1key nvarchar(20) = 'ResaID'
DECLARE #table2 nvarchar(20) = 'Extras'
DECLARE #table2key nvarchar(20) = 'ResaID'
DECLARE #viewname varchar(20) = 'v_myview'
DECLARE #sql varchar(max) = ''
SELECT #sql += '], a.[' + column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table1
SELECT #sql += '], b.[' + column_name
FROM
(
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table2
EXCEPT
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table1
) x
SELECT
#sql = 'CREATE view ' +#viewname+ ' as SELECT '
+ STUFF(#sql, 1, 3, '') + '] FROM ['
+#table1+ '] a JOIN ['+ #table2
+'] b ON ' + 'a.' + #table1key + '=b.' + #table2key
EXEC(#sql)
You can simply solve this using a dynamic sql query.
DECLARE #V_SQL AS NVARCHAR(2000)='' --variable to store dynamic query
,#V_TAB1 AS NVARCHAR(200)='TEMP' --First Table
,#V_TAB2 AS NVARCHAR(200)='Extras' --Second Table
,#V_CONDITION AS NVARCHAR(2000)='A.ResaID = B.ResaID' --Conditions
SELECT #V_SQL = STUFF(
( SELECT ', '+TCOL_NAME
FROM
( SELECT 'A.'+S.NAME AS TCOL_NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB1
UNION ALL
SELECT 'B.'+S.NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB2
AND S.NAME NOT IN (SELECT S.NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB1)
) D
FOR XML PATH('')
),1,2,'')
EXECUTE ('SELECT '+#V_SQL+'
FROM '+#V_TAB1+' AS A
INNER JOIN '+#V_TAB2+' AS B ON '+#V_CONDITION+' ')
I have a stored procedure that dynamically creates a pivot query.
The procedure works and returns the correct data.
Now I have a requirement to show this data in a reporting system that can only pull from a table or view. Since you can not create a dynamic query in a view I tried to do a select from using openquery.
Example '
Select * from OpenQuery([MyServername], 'Exec
Instance.Schema.StoredProcedure')
I get the error back
"the linked server indicates the object has no columns".
I assume this is because of the first select statement that is stuffing the variable with column names.
CODE FROM PROCEDURE
ALTER PROCEDURE [dbo].[FuelCombustorMatrix]
AS
BEGIN
-- Use Master
SET NOCOUNT ON
Declare #cols nvarchar(2000),
#Tcols nvarchar(2000),
#Sql nvarchar (max)
select #cols = stuff ((
Select distinct '], ['+ModelName + ' ' + CombustorName
from CombustorFuel cf
join Model m on cf.modelid = m.modelid
join Combustors cb on cf.CombustorID = cb.CombustorID
where cf.CombustorID > 0
for XML Path('')
),1,2,'')+']'
Set #Tcols = replace(#Cols, ']', '] int')
--Print #Tcols
--Print #Cols
Set #Sql = 'Select GasLiquid, FuelType, '+ #Cols +'
from
(
Select GasLiquid, FuelType, ModelName+ '' '' +CombustorName ModelCombustor, CombFuelStatus+''- ''+CombFuelNote CombFuelStatusNote
from Frames f
join Family fa on f.Frameid = fa.frameid
join Model m on fa.FamilyID = m.FamilyID
join CombustorFuel cf on m.Modelid = cf.modelid
Join Combustors c on cf.CombustorId = c.CombustorID
join FuelTypes ft on cf.FuelTypeID = ft.FuelTypeID
where cf.CombustorFuelID > 0
and CombustorName <> ''''
) up
Pivot
(max(CombFuelStatusNote) for ModelCombustor in ('+ #Cols +')) as pvt
order by FuelType'
exec (#Sql)
END