SQL Server 2008 R2: Invalid column name in PIVOT query - sql-server

I have a dynamic pivot query and I want to pivot on businessaccountnumber which I know exist in the transaction_table but it keeps returning that "Invalid column name 'bizi'."- for line 1.
DECLARE #Output nvarchar(max) = N''
DECLARE #PivotList varchar(max)
SELECT
#PivotList = COALESCE(#PivotList + ', ', N'') + N'[' + bizid + N']'
FROM (SELECT DISTINCT
BusinessAccountNumber [bizid]
FROM transaction_table
WHERE postingdate BETWEEN '1/01/2015' AND '2/01/2015'
) AS CustProds;
SET #Output = 'SELECT [bizName],[bizi]
, ' + #PivotList + '
FROM ( select businessname as [bizName],businessaccountnumber as [bizi],
sum((Transactionamount*(-1))) as [Transactionamount]
FROM transaction_table
WHERE postingdate between ''1/01/2015'' and ''2/01/2015''
GROUP BY businessaccountnumber,businessname) as P
PIVOT ( SUM(Transactionamount) FOR P.bizi IN (' + #PivotList + ') ) AS PVT'
EXEC sp_executesql #Output;
EDIT: Thanks to Backs for pointing out my error but now I have a new error.
the output I am looking for is:
Date | bizid12| bizid13| bizid14...
01/01/2015| $1 | $3 | $56
01/02/2015| $12 | $34 | $3
.....
DECLARE #Output nvarchar(max) = N''
DECLARE #PivotList varchar(max)
SELECT
#PivotList = COALESCE(#PivotList + ', ', N'') + N'[' + bizid + N']'
FROM (SELECT DISTINCT
BusinessAccountNumber [bizid]
FROM transaction_table
WHERE postingdate BETWEEN '1/01/2015' AND '2/01/2015'
) AS CustProds;
SET #Output = 'SELECT [sp_date]
, ' + #PivotList + '
FROM ( select Convert(varchar,postingdate,101) as [sp_date]
,businessaccountnumber as [bizi],
sum((Transactionamount*(-1))) as [Transactionamount]
FROM transaction_table
WHERE postingdate between ''1/01/2015'' and ''2/01/2015''
GROUP BY businessaccountnumber) as P
PIVOT ( SUM(Transactionamount) FOR P.bizi IN (' + #PivotList + ') ) AS PVT'
EXEC sp_executesql #Output;
Error now says:
Msg 8180, Level 16, State 1, Line 1
Statement(s) could not be prepared.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'Qry12090'.
Msg 1056, Level 15, State 1, Line 1
The number of elements in the select list exceeds the maximum allowed number of 4096 elements.

You can't select bizi in query SELECT [bizName],[bizi] using it in PIVOT FOR P.bizi IN. Remove [bizi] from select statement

Related

Dynamic SQL Query To Temp Table In SSIS

I am attempting to create a global temp table based off of a dynamic SQL query. I am using an execute SQL task. Thus far, whenever I execute it, the temp table is not created. Below is my script. I have altered my connection property so that it retains the connection and I set the delay validation to true in the data flow task. When I query for the global temp table, the object doesn't exist.
drop table if exists ##HOCExp
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(ShortLabel)
FROM (SELECT p.ShortLabel FROM dbo.TECHEnumValue AS p
JOIN dbo.CNTHospitalOrClinicExposure AS o
ON p.EnumValue = o.MPLEntityExposureBasis
where p.MyEnumType_ID = 610 and p.ShortLabel <>''
GROUP BY p.ShortLabel) AS x;
SET #sql = N'
SELECT EntityFK, ' + STUFF(#columns, 1, 2, '') + '
into ##HOCExp
FROM
(
SELECT p.ShortLabel
, o.MPLEntityExposureUnit
, concat(o.MyInsuredItemHospitalOrClinic_ClassID
, o.MyInsuredItemHospitalOrClinic_ID) as EntityFK
FROM dbo.TECHEnumValue AS p
INNER JOIN dbo.CNTHospitalOrClinicExposure AS o ON p.EnumValue = o.MPLEntityExposureBasis
where p.EnumValue <>0 and p.MyEnumType_ID = 610 and o.MyInsuredItemHospitalOrClinic_ID <>0
) AS j
PIVOT
(
SUM(MPLEntityExposureUnit) FOR ShortLabel IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
--PRINT #sql;
EXEC sp_executesql #sql;
select * from ##HOCExp

SQL Server loop through dynamic query

I have a procedure where I pass temporary table name as parameter. For each dataset inside I need to get rowcount. How to achieve this?
I need something like:
CREATE PROCEDURE sp_processing
#temp_table_name varchar(50)
AS
DECLARE #log varchar(max)
/* get list of keys inside temp_table_name */
/* just a pseudo-code example */
SET #l_cursor = CURSOR FOR
SELECT Key1, Key2, Key3, count(*)
FROM #temp_table_name -- table name passed as text
GROUP by Key1, Key2, Key3;
WHILE "there are results"
BEGIN
#log += #Key1 +', '+ #Key2 +', '+ #Key3 +', '+ #count + CHAR(13)+CHAR(10);
END
UPDATE log_table SET log_column = #log WHERE....;
END /* procedure */
Is there a way to loop this?
I know I have option to fetch results to a table type and THEN loop, but that requires to use a table type, so wondering if this is achievable without a table variable.
EDIT: I need just need to print count for each set of keys.
This worked for me:
DECLARE #l_sql nvarchar(max)
DECLARE #temp_table_name varchar(50) = 'SOME_TABLE'
DECLARE #combinedString varchar(max)
SET #l_sql = 'SELECT #combinedString = COALESCE(#combinedString, '''') + convert(varchar,[Key1]) +'', ''+ convert(varchar,[Key3]) +'': ''+ convert(varchar,COUNT(*)) + ''| '' + CHAR(13)+CHAR(10) '
+ ' FROM ' + #temp_table_name
+ ' GROUP BY [Key1], [Key3]'
+ ' ORDER BY [Key1], [Key3]';
EXECUTE sp_executesql #l_sql, N'#combinedString varchar(max) OUTPUT', #combinedString = #combinedString OUTPUT ;
SELECT #combinedString
Result:
1, 1: 4|
1, 2: 2|
1, 3: 1|
2, 5: 1|
You should always try to avoid looping and cursor. This is a set based solution for your case. Please review (specially the update filter) and see if it suits your needs.
CREATE PROCEDURE sp_processing
#temp_table_name varchar(50)
AS
BEGIN
DECLARE #DynamicSQL VARCHAR(MAX) = '
;WITH LogRecords AS
(
SELECT
LogRecord =
ISNULL(T.Key1, '''') + '','' +
ISNULL(T.Key2, '''') + '','' +
ISNULL(T.Key2, '''') + '','' +
CONVERT(VARCHAR(20), COUNT(1))
FROM
QUOTENAME(''' + #temp_table_name + ''') AS T
GROUP BY
T.Key1,
T.Key2,
T.Key3
)
UPDATE L SET
log_column = STUFF(
(
SELECT
R.LogRecord + CHAR(13) + CHAR(10)
FROM
LogRecords AS R
FOR XML
PATH('')
),
1, 1, '')
FROM
log_table AS L
WHERE
L.IdFilter = 999999999'
PRINT #DynamicSQL
-- EXEC (#DynamicSQL)
END

SQL Server remove trailing comma from XML path

I have the following code that pulls what my columns are called within a given table of mine:
SELECT
column_name + ','
FROM
information_schema.columns
WHERE
table_name = 'maintReq'
FOR XML PATH('')
And I am wanting to place that into my current query:
SET IDENTITY_INSERT maintReq ON;
GO
INSERT INTO maintReq
OUTPUT Inserted.ID
VALUES ((SELECT ISNULL(MAX(id) + 1, 0)
FROM maintReq WITH(SERIALIZABLE, UPDLOCK)
),'MAYBE', 'true');
SET IDENTITY_INSERT maintReq OFF;
I've tried to do the following myself:
SET IDENTITY_INSERT maintReq ON;
GO
INSERT INTO maintReq (
SELECT
column_name + ','
FROM
information_schema.columns
WHERE
table_name = 'maintReq'
for
xml path('')
)
OUTPUT Inserted.ID
VALUES (
(
SELECT
ISNULL(MAX(id)+1,0)
FROM
maintReq WITH(SERIALIZABLE, UPDLOCK)
),'MAYBE', 'true'
);
SET IDENTITY_INSERT maintReq OFF;
But with that I am getting the error of:
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'SELECT'.
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near ')'.
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near ','.
Not sure if that error is called by the extra comma that was added to the output of the XML path or if its something else?
My full stored procedure looks like this:
DECLARE #SQLQuery VARCHAR(MAX);
SET #SQLQuery = 'SET IDENTITY_INSERT ' + #val1 + ' ON
INSERT INTO ' +
#val1 + '
OUTPUT Inserted.ID
VALUES ' +
'(
(
SELECT
ISNULL(MAX(id)+1,0)
FROM
' + #val1 + ' WITH(SERIALIZABLE, UPDLOCK)
),''' + #val2 + ''', ''' + #val3 + '''
) ' +
'SET IDENTITY_INSERT ' + #val1 + ' OFF;'
EXEC [dbo].[_chkQ] #SQLQuery
The above SP is what I am currently getting this error:
An explicit value for the identity column in table 'maintReq' can only
be specified when a column list is used and IDENTITY_INSERT is ON.
Thanks to #Pரதீப் this is the final working query code:
SET #SQLQuery = 'SET IDENTITY_INSERT ' + #val1 + ' ON
INSERT INTO ' + #val1 + '(' +
Stuff(
(SELECT
',' + quotename(column_name)
FROM
information_schema.columns
WHERE
table_name = '' + #val1 + ''
FOR xml path('')
), 1, 1, ''
) +
')
OUTPUT Inserted.ID
VALUES ' +
'(
(
SELECT
ISNULL(MAX(id)+1,0)
FROM
' + #val1 + ' WITH(SERIALIZABLE, UPDLOCK)
),''' + #val2 + ''', ''' + #val3 + '''
) ' +
'SET IDENTITY_INSERT ' + #val1 + ' OFF;'
You need to use dynamic sql
DECLARE #col_list VARCHAR(8000)= ''
SET #col_list = Stuff((SELECT ',' + quotename(column_name) --"quotename" is to escape illegal characters
FROM information_schema.columns
WHERE table_name = 'maintReq'
FOR xml path('')), 1, 1, '')
SET IDENTITY_INSERT maintReq ON;
EXEC ('
INSERT INTO maintReq ('+#col_list+')
OUTPUT Inserted.ID
VALUES (
(SELECT
ISNULL(MAX(id)+1,0)
FROM
maintReq WITH(SERIALIZABLE, UPDLOCK)
),''MAYBE'', ''true''
); ')
SET IDENTITY_INSERT maintReq OFF;

CTE having dynamic variable

I have these 2 example of CTE statement, one is hardcoded and the other is dynamic. The hardcoded works but not the dynamic. Can you check what's wrong with my dynamic statement? Thanks
-- THIS WORKS
WITH CTE AS
(
SELECT TOP 1 *
FROM Citi_v823_21Nov2013.dbo.GroupRelation_Audit
WHERE Citi_v823_21Nov2013.dbo.GroupRelation_Audit.ParentEntityIDCounter = #ParentEntityIDCounter
AND Citi_v823_21Nov2013.dbo.GroupRelation_Audit.ChildEntityIDCounter = #ChildEntityIDCounter
AND IsNull(Citi_v823_21Nov2013.dbo.GroupRelation_Audit.AuditDateModified, '1900-01-01') < GETDATE()
ORDER BY GroupRelationCounter DESC
)
UPDATE CTE SET DateEffectiveTo = #DateEffectiveFrom_GroupRelation
--THIS DOESN'T WORK
DECLARE #TargetDB NVARCHAR(Max)
DECLARE #SourceDB NVARCHAR(Max)
DECLARE #DateEffectiveFrom_GroupRelation DATETIME
DECLARE #UpdateRecords_GroupRelation NVARCHAR(Max)
SET #TargetDB = 'Citi_v823_21Nov2013'
SET #SourceDB = 'UATCitiv82320131018'
SET #DateEffectiveFrom_GroupRelation = '2013-09-29'
SET #UpdateRecords_GroupRelation = '
;WITH CTE AS
(
SELECT TOP 1 *
FROM ' + #TargetDB + '.dbo.GroupRelation_Audit
WHERE ' + #TargetDB + '.dbo.GroupRelation_Audit.ParentEntityIDCounter = ' + CONVERT(NVARCHAR(Max), #ParentEntityIDCounter) +'
AND ' + #TargetDB + '.dbo.GroupRelation_Audit.ChildEntityIDCounter = ' + CONVERT(NVARCHAR(Max), #ChildEntityIDCounter) +'
AND IsNull(' + #TargetDB + '.dbo.GroupRelation_Audit.AuditDateModified, ''1900-01-01'') < GETDATE() ''
ORDER BY ' + #TargetDB + '.dbo.GroupRelation_Audit.GroupRelationCounter DESC
)'
UPDATE CTE SET DateEffectiveTo = #DateEffectiveFrom_GroupRelation
EXEC sp_executesql #UpdateRecords_GroupRelation
Move your UPDATE statement inside the SQL statement.
The CTE is locally-scoped, so that statement won't known what CTE is and will simply throw an invalid object error.
Sample code:
declare #sql nvarchar(max)
select *
into ##t
from
(select 3 as b) tmp
select * from ##t;
set #sql = ';WITH a as (select 1 as b) update ##t set b = (select top 1 * from a) '
EXEC sp_executesql #sql
select * from ##t
drop table ##t

SQL Server Syntax Error on PIVOT

Can anyone please help me with the PIVOT table syntax error as I am using this for the First time.
DECLARE #sql AS varchar(max)<br/>
DECLARE #pivot_list AS varchar(max) <br/>
DECLARE #select_list AS varchar(max) <br/>
SELECT #pivot_list = COALESCE(#pivot_list + ', ', '') + '[' + CONVERT(varchar, STATE_NAME) + ']'<br/>
,#select_list = COALESCE(#select_list + ', ', '') + '[' + CONVERT(varchar, STATE_NAME) + '] AS [' + CONVERT(varchar, STATE_NAME) + ']'
FROM (
SELECT DISTINCT name as STATE_NAME
FROM k12_dms_states
) AS PIVOT_CODES
SET #sql = '
SELECT COUNT(k12_dms_contacts_institution_jobtitles.id) as total_count
,k12_dms_job_titles.title as job_title,' + #select_list + '
FROM k12_dms_institution_master
INNER JOIN k12_dms_contacts_institution_jobtitles ON k12_dms_institution_master.id = k12_dms_contacts_institution_jobtitles.inst_id
INNER JOIN k12_dms_job_titles ON k12_dms_job_titles.id = k12_dms_contacts_institution_jobtitles.job_title_id
GROUP BY k12_dms_job_titles.title
PIVOT (
total_count
FOR STATE_NAME IN (
' + #pivot_list + '
)
) AS pvt
'
PRINT #sql
EXEC (#sql)
I am getting this error: -
Msg 156, Level 15, State 1, Line 8
Incorrect syntax near the keyword 'PIVOT'.
PIVOT belongs in the FROM clause. It needs to occur before any GROUP BY clause.
(Further edits based on commenting, to try to correct):
SET #sql = '
SELECT
k12_dms_job_titles.title as job_title,' + #select_list + '
FROM k12_dms_institution_master
INNER JOIN k12_dms_contacts_institution_jobtitles ON k12_dms_institution_master.id = k12_dms_contacts_institution_jobtitles.inst_id
INNER JOIN k12_dms_job_titles ON k12_dms_job_titles.id = k12_dms_contacts_institution_jobtitles.job_title_id
PIVOT (
COUNT(k12_dms_contacts_institution_jobtitles.id)
FOR STATE_NAME IN (
' + #pivot_list + '
)
) AS pvt
'

Resources