I am using this simple code to pivot some column.
But I can't make it work due to that error.
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
DECLARE #style_dy AS VARCHAR (100) = 'S1415MBS06'
DECLARE #query AS VARCHAR(8000)
DECLARE #con AS VARCHAR(8000)
SET #con = STUFF((SELECT distinct ',' + QUOTENAME(Size_id)
FROM iPLEXSTY_SIQ
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT *
FROM (
SELECT DISTINCT a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt, (c.Description + c.Resource_id) AS comb_size,a.Qty,a.Size_id
from iPLEXSTY_SIQ a
INNER JOIN iPLEX_BULK_PO_DET b on b.upload_batch_id = a.Batch_id
INNER JOIN iPLEXCOLORS c on c.Seq_no = a.Seq_no
WHERE IO_no = #IO_dy AND Style_id = #style_dy //ERROR HERE
GROUP BY a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt,(c.Description + c.Resource_id),a.Qty,A.Size_id
) as s
PIVOT
(
SUM(Qty)
FOR Size_id IN (' +#con+ ')
)AS pvt'
EXEC(#query)
addition to another answer
just single quotes to the variable names used in the query
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
DECLARE #style_dy AS VARCHAR (100) = 'S1415MBS06'
DECLARE #query AS VARCHAR(8000)
DECLARE #con AS VARCHAR(8000)
SET #con = STUFF((SELECT distinct ',' + QUOTENAME(Size_id)
FROM iPLEXSTY_SIQ
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT *
FROM (
SELECT DISTINCT a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt, (c.Description + c.Resource_id) AS comb_size,a.Qty,a.Size_id
from iPLEXSTY_SIQ a
INNER JOIN iPLEX_BULK_PO_DET b on b.upload_batch_id = a.Batch_id
INNER JOIN iPLEXCOLORS c on c.Seq_no = a.Seq_no
WHERE IO_no = '''+#IO_dy+''' AND Style_id = '''+#style_dy+''' //ERROR HERE
GROUP BY a.Po_no,a.Article_id,a.Season_id,a.Customer_id,a.Destn_id,b.planned_dt,(c.Description + c.Resource_id),a.Qty,A.Size_id
) as s
PIVOT
(
SUM(Qty)
FOR Size_id IN (' +#con+ ')
)AS pvt'
EXEC(#query)
and also as another answer explains to set values to varchar using default keyword
You can't declare and initialize value of variable using "=". So instead of:
DECLARE #IO_dy AS VARCHAR(100) = '>9C604-M'
Use
DECLARE #IO_dy AS VARCHAR(100) DEFAULT '>9C604-M'
^^^^^^^
See this for syntax
Related
I want to run a query that shows me all columns from all tables in a database with the datatype varchar and a maximum length of 8000 characters.
This is my code so far.
DECLARE #tabs VARCHAR(MAX);
SET #tabs =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #cols VARCHAR(MAX)
SET #cols =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME] + '.' + [COLUMN_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #query VARCHAR(MAX) = 'SELECT ' + #cols + ' FROM ' + #tabs
EXEC sp_sqlexec #query
When I run the query I get all the column names, but not the values in the columns. It's empty. No 'NULL'-values. As if #cols is interpreted as simple string maybe.
Why?
(When I read out #cols and #tabs they are correct.)
I guess there is one table available in your database which have column with VARCHAR datatype and 8000 length but that table don't have any records. Try by including only those column and table which have at least one record available.
You can try below. Check it and let me know if it works.
DECLARE #tabs VARCHAR(MAX) = ''
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #tabs = #tabs+ISNULL(','+TABLE_NAME, '')
FROM TABLENAME
DECLARE #cols VARCHAR(MAX) = '';
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME], ITBL.[COLUMN_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #cols = #cols+ISNULL(','+[TABLE_NAME]+'.'+[COLUMN_NAME], '')
FROM TABLENAME
IF LEN(#cols) > 0 AND LEN(#tabs) > 0
BEGIN
DECLARE #query VARCHAR(MAX) = 'SELECT ' + STUFF(#cols,1,1,'') + ' FROM ' + STUFF(#tabs,1,1, '')
EXEC sp_sqlexec #query
END
ELSE
BEGIN
PRINT 'No Column available with data where it''s datatype is VARCHAR and length is 8000'
END
i have a pivot table that display student absence, there is not problem in executing and the result of the pivot but if there is no value it display null, i want to display 0 not a null. i googled and found some ways i try use them but i can't do it. can anyone tell me please?
this my pivot table code:
create proc [dbo].[get_st_abs_by_stage]
#Stage_ID smallint
as
CREATE TABLE #SummaryTable
(
SName nvarchar(50),
CName nvarchar(50),
Stage_ID SmallInt,
Sum_Abs SmallInt
)
delete from #SummaryTable
INSERT INTO #SummaryTable(SName, CName, Stage_ID, Sum_Abs)
SELECT Student_tbl.SName,Courses_tbl.CName,Stages_tbl.Stage_ID,Sum_Abs from Absence_Summary_tbl
inner join Student_tbl on Student_tbl.S_ID = Absence_Summary_tbl.S_ID
inner join Stages_tbl on Stages_tbl.Stage_ID = Student_tbl.Stage_ID
inner join Courses_tbl on Courses_tbl.C_ID = Absence_Summary_tbl.C_ID
where Stages_tbl.Stage_ID = #Stage_ID;
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT SName,' + #cols + ' from
(
select SName, CName, Sum_Abs
from #SummaryTable
) x
pivot
(
sum(Sum_Abs)
for CName in (' + #cols + ')
) p '
execute(#query);
You can generate another variable with isnull for cols. Something like this
select #cols = STUFF((SELECT ',' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
select #isnull_cols = STUFF((SELECT ', isnull(' + QUOTENAME(CName) + ', 0) as ' + QUOTENAME(CName)
from #SummaryTable
where Stage_ID = #Stage_ID
group by CName
order by CName
FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT SName,' + #isnull_cols + ' from
(
select SName, CName, Sum_Abs
from #SummaryTable
) x
pivot
(
sum(Sum_Abs)
for CName in (' + #cols + ')
) p '
execute(#query);
Hi all I have written the following Procedure to display the results as pivot as per the requirement
DECLARE #values AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #values = STUFF(
(
SELECT DISTINCT ',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = 'SELECT viewName1.*, pValues.Code, ' + #values + ' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #values + ')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
But when the value and column names are same in my xTable and viewName1 I am getting that error how can I resolve this. I tried with alas but I am not getting the expected result so can some one help me.
Sample is I am having a ColumnName as TopBrand in my table xTable, this can be a value in my viewName1 like for X Column TopBrand can be a value.
I think you need to have a separate list for FOR and IN clauses and the former should include the alias:
DECLARE #valuesFor AS NVARCHAR(MAX),
#valuesIn AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #valuesFor = STUFF(
(
SELECT DISTINCT N',pValues.[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SELECT #valuesIn = STUFF(
(
SELECT DISTINCT N',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = N'SELECT viewName1.*, pValues.Code, ' + #valuesFor + N' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #valuesIn + N')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
I have two tables named Emp and TrainingTable
Emp columns (EmpId(PK, int, not null), EmpName(nchar(10), null))
TrainingTable columns (EmpId(FK, int, null), TainingId(int, null), TainingName(nvarchar(50), not null))
Code:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(TainingId)
from TrainingTable
group by TainingId
order by TainingId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EmpName,' + #cols + ' from
(
select Emp.EmpName, TainingName, TainingId
from TrainingTable INNER JOIN Emp ON TrainingTable.EmpId = Emp.EmpId
) x
pivot
(
max(TainingName)
for TainingId in (' + #cols + ')
) p '
execute(#query)
Now what I want to do is to rename the columns 1,2,3.. with Training1,Traning2,.. and so on..
the result table may change depending on data. columns may increase..
I tried almost every thing .. but not getting the correct way to achieve it.
Try this
You need to cast your column Using CAST()
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME('Training' + CAST(TainingId AS Varchar(50)))
from TrainingTable
group by TainingId
order by TainingId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT EmpName,' + #cols + ' from
(
select Emp.EmpName,
TainingName,
col = ''Training'' + cast(TainingId as varchar(10))
from TrainingTable
INNER JOIN Emp ON TrainingTable.EmpId = Emp.EmpId
) x
pivot
(
max(TainingName)
for col in (' + #cols + ')
) p '
execute(#query)
Refer
I have google online this question and for the life of me couldn't figure out why this kept throwing errors, any help is appreciated.
Conversion failed when converting the nvarchar value 'SELECT #orderid
= t.orderid FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY creationdatetime DESC) AS row FROM
[intranet].[dbo].handbook_appendix_data WHERE id = ' to data type int.
DECLARE #sql nvarchar(500)
DECLARE #table varchar(40)
SET #table = 'handbook_section_data';
SET #table = 'handbook_appendix_data';
DECLARE #parentid INT
DECLARE #id INT
DECLARE #published INT
DECLARE #orderid INT
SET #parentid = 2
SET #id = -1
SET #published = 1
SET #sql = N'SELECT #orderid = t.orderid FROM
(SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY creationdatetime DESC) AS row FROM [intranet].[dbo].'+#table+' WHERE id = '+#id+' AND published = '+#published+') AS t
WHERE t.published = '+#published+' AND t.row = 1';
EXEC SP_EXECUTESQL #sql, N'#orderid INT OUTPUT', #orderid = #orderid OUTPUT --Get the OrderID from ID
PRINT #orderid
You need to convert your #id and #published ints to a varchar
convert(varchar(50),#published)
ie
SET #sql = N'SELECT #orderid = t.orderid FROM
(SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY creationdatetime DESC) AS row FROM [intranet].[dbo].'+#table+' WHERE id = '+ convert(varchar(50),#id) +' AND published = '+ convert(varchar(50),#published) +') AS t
WHERE t.published = '+convert(varchar(50), #published) +' AND t.row = 1';
A better solution would be to avoid the string concatenation, and pass the #id and #published parameters using the sp_executesql as you are already doing with #orderid, or to question the requirement for dynamic SQL at all?
You need to cast the integer variables to a character type:
....
WHERE id =' + cast(#id as varchar(32)) + ' AND published = ' + cast(#published as varchar(32)) + ') AS t ...
WHERE t.published = '+#published+' AND t.row = 1'
#published is an int. SQL Server has decided that + must be between two ints, and is trying to convert the string to an int.
To stop this, force #published to be a string instead - then it's adding two strings (concatenation) instead:
WHERE t.published = '+CONVERT(varchar(10),#published)+' AND t.row = 1'