tsql dynamic table stored procedure - sql-server

I wrote a long list of stored procedure to update some tables, when finished I realized that most of this stored procedure were very similar each other.. with only few fields changing
then I was wondering to make a single stored procedure and this is what I did:
CREATE PROCEDURE dbo.Save_All
(
#UID nvarchar(100) = NULL, --All
#Table nvarchar(40) = NULL, --All
#ID int = 0, --All
...
#SubCategory nvarchar(50) = NULL, -- Ticker
#Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE #S nvarchar(max)='',
#P nvarchar(max)='',
#cols1 nvarchar(max)='',
#cols2 nvarchar(max)='',
#cols3 nvarchar(max)=''
SELECT #cols1= ISNULL(#cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID' Order by colID) AS Columns;
SELECT #cols2= ISNULL(#cols2 + ',','') + '#_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID' Order by colID) AS Columns;
SELECT #cols3= ISNULL(#cols3 + ',','') + QUOTENAME(name)+'=#_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID' Order by colID) AS Columns;
SELECT #cols1 = STUFF(#cols1, 1, 1, '');
SELECT #cols2 = STUFF(#cols2, 1, 1, '');
SELECT #cols3 = STUFF(#cols3, 1, 1, '');
IF (#ID=0 OR #ID is null)
SET #S = N'INSERT INTO #_Table ('+ #cols1 + ') VALUES ('+#cols2+')'
ELSE
SET #S = N' UPDATE #_Table SET ' +#cols3 +' WHERE ID=#_ID'
--PRINT #S
SET #P= '#_UID nvarchar(100),
#_Table nvarchar(40),
#_ID int,
...
#_SubCategory nvarchar(50),
#_Link nvarchar(300)'
EXEC sp_executesql #S,#P,#UID,#Table,#ID,...,#SubCategory,#Link
END
SET NOCOUNT OFF
But, although the list of parameters is quite long (I amended most of them in the example) it does not include all fields of all the tables and therefore return an error in many cases..
Solution would be to include in #cols1/2/3 only the fields that are defined also as parameter.. or to set to null the relative #_xx
But this is beyond my current knowledge..
By the way.. what about the stored procedure? which unacceptable mistakes does it contain?
Thanks!
Joe

Well, I found the solution and was easier than thought..
moved
#P definition on top and add
SET #P= '...'
on top and add
AND CHARINDEX('#_'+name+' ',#P)>0
to the rules to create the 3
#cols
All together:
CREATE PROCEDURE dbo.Save_All
(
#UID nvarchar(100) = NULL, --All
#Table nvarchar(40) = NULL, --All
#ID int = 0, --All
...
#SubCategory nvarchar(50) = NULL, -- Ticker
#Link nvarchar(300) = NULL -- Ticker
)
AS
SET NOCOUNT ON;
BEGIN
DECLARE #S nvarchar(max)='',
#P nvarchar(max)='',
#cols1 nvarchar(max)='',
#cols2 nvarchar(max)='',
#cols3 nvarchar(max)=''
SET #P= '#_UID nvarchar(100),
#_Table nvarchar(40),
#_ID int,
...
#_SubCategory nvarchar(50),
#_Link nvarchar(300)'
SELECT #cols1= ISNULL(#cols1 + ',','') + QUOTENAME(name)
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID'
AND CHARINDEX('#_'+name+' ',#P)>0 Order by colID) AS Columns;
SELECT #cols2= ISNULL(#cols2 + ',','') + '#_' + name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID'
AND CHARINDEX('#_'+name+' ',#P)>0Order by colID) AS Columns;
SELECT #cols3= ISNULL(#cols3 + ',','') + QUOTENAME(name)+'=#_'+ name
FROM (SELECT top (100) name FROM sys.columns
WHERE id=OBJECT_ID(#Table) and name<>'ID'
AND CHARINDEX('#_'+name+' ',#P)>0Order by colID) AS Columns;
SELECT #cols1 = STUFF(#cols1, 1, 1, '');
SELECT #cols2 = STUFF(#cols2, 1, 1, '');
SELECT #cols3 = STUFF(#cols3, 1, 1, '');
IF (#ID=0 OR #ID is null)
SET #S = N'INSERT INTO #_Table ('+ #cols1 + ') VALUES ('+#cols2+')'
ELSE
SET #S = N' UPDATE #_Table SET ' +#cols3 +' WHERE ID=#_ID'
--PRINT #S
EXEC sp_executesql #S,#P,#UID,#Table,#ID,...,#SubCategory,#Link
END
SET NOCOUNT OFF
well, a little rough.. surely there are better way to build it but so far.. seems it work well
thanks everybody for reading!
Joe

Related

Stored procedure : getting error "Must declare the scalar variable "#id". " when executing procedure

I need some help creating a stored procedure in SQL Server.
This is my code
CREATE PROCEDURE [dbo].[PROC_TABLE_ELEMENTS]
#id nvarchar(max)
AS
DECLARE #sql varchar(max) = '', #col_list varchar(max) = ''
SET #col_list = (SELECT DISTINCT QOUTENAME(columnName) + ','
FROM VW_FORM_ELEMENTS_DATA
FOR XML PATH(''))
SET #col_list = LEFT(#col_list, LEN(#col_list) - 1)
SET #sql = N'SELECT [newId], [modifiedDate], [modifiedBy], [modifiedBy]' + #col_list +
' FROM (SELECT newId, value, columnName, modifiedDate, modifiedBy
FROM VW_FORM_ELEMENTS_DATA
WHERE newId = #id) a
PIVOT
(MAX([value]) FOR [columnName] IN (' + #col_list + ')) pv'
EXEC (#sql)
I get this error:
Must declare the scalar variable "#id".
this works:
CREATE PROCEDURE [dbo].[PROC_TABLE_ELEMENTS]
#id nvarchar(max)
AS
declare #sql varchar(max)='',#col_list varchar(max)=''
set #col_list = (select distinct quotename(columnName)+',' from VW_FORM_ELEMENTS_DATA
for xml path(''))
set #col_list = left (#col_list,len(#col_list)-1)
set #sql = 'select [screenId],[newId],[modifiedDate],[modifiedBy],[modifiedBy]'+#col_list+' from
(SELECT screenId, newId, value, columnName, modifiedDate, modifiedBy FROM VW_FORM_ELEMENTS_DATA where screenId = ''' + #id + ''') a
pivot (max([value]) for [columnName] in ('+#col_list+'))pv'
exec (#sql)
This should work in SQL Server.

loop to add value in dynamic OR statement

I broke this query down to the most basic. I need to add an OR statement dynamically, which includes a variable. I need to get any id and its corresponding id with an underscore. So, my resulting #SQL to execute would be:
create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values ('5','31'),
('5','31_00000'),
('5','33'),
('5','33_00000'),
('5','25'),
('5','25_00000'),
('5','HD_00000'),
('5','HD')
--
DECLARE
#OrganizationId int = 5,
#OriginId nvarchar(256) = N'31,25,33'
create table #inVars(id int NOT NULL IDENTITY PRIMARY KEY, origins varchar(256))
insert into #inVars(origins)
Values ('31'),
('33'),
('25')
DECLARE #SQL NVARCHAR(MAX),
#ParamDefinition NVARCHAR(MAX)
SET #ParamDefinition = N'#OrganizationId int,
#OriginId nvarchar(256)'
SET #SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId'
IF ISNULL(#OriginId,'') <> ''
SET #SQL = #SQL + ' AND OrigID in (''' + #OriginId + ''') '
DECLARE #counter INT = 1, #max INT = 0, #Origin nvarchar(50), #SQL_2 nvarchar(max)
SELECT #max = COUNT(id) FROM #inVars
WHILE #counter <= #max
BEGIN
SET #Origin = '_%'
SET #Origin = (select origins from #invars where id = CAST(#counter as varchar(10))) + #Origin
SET #SQL_2 = N' OR OrigID LIKE ''' + #Origin + ''' '
SET #SQL_2 = #SQL + #SQL_2
print(#SQL_2)
SET #counter = #counter + 1
END
EXEC sp_executesql #SQL_2,#ParamDefinition,#OrganizationId,#OriginId
drop table #inVars
drop table #Test
Here is how my query is executing now:
SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId AND OrigID in ('31,25,33') OR OrigID LIKE '31_%'
SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId AND OrigID in ('31,25,33') OR OrigID LIKE '33_%'
SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId AND OrigID in ('31,25,33') OR OrigID LIKE '25_%'
This is my desired result:
SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId AND OrigID in ('31,25,33') OR OrigID LIKE '31_%'
OR OrigID LIKE '33_%'
OR OrigID LIKE '25_%'
A few problems: You can't concatenate a NULL with a string EVER; the result is always NULL (please look at the IF #Origin IS NOT NULL line). In your loop, you should be updating #SQL, not #SQL_2. Lastly, you should wrap ORs in parens so the logic is always explicit.
SET NOCOUNT ON
create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values ('5','31'),
('5','31_00000'),
('5','33'),
('5','33_00000'),
('5','25'),
('5','25_00000'),
('5','HD_00000'),
('5','HD')
DECLARE
#OrganizationId int = 5,
#OriginId nvarchar(256) = N'31,25,33'
create table #inVars(id int NOT NULL IDENTITY PRIMARY KEY, origins varchar(256))
insert into #inVars(origins)
Values ('31'),
('33'),
('25')
DECLARE #SQL NVARCHAR(MAX),
#ParamDefinition NVARCHAR(MAX)
SET #ParamDefinition = N'#OrganizationId int,
#OriginId nvarchar(256)'
SET #SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId'
IF ISNULL(#OriginId,'') <> ''
SET #SQL = #SQL + ' AND (OrigID in (''' + #OriginId + ''') '
DECLARE #counter INT = 1, #max INT = 0, #Origin nvarchar(50), #SQL_2 nvarchar(max)
SELECT #max = COUNT(id) FROM #inVars
WHILE #counter <= #max
BEGIN
SET #Origin = '_%'
SET #Origin = (select origins from #invars where id = CAST(#counter as varchar(10))) + #Origin
IF #Origin IS NOT NULL
BEGIN
SET #SQL_2 = N' OR OrigID LIKE ''' + #Origin + ''' '
SET #SQL = #SQL + #SQL_2
END
SET #counter = #counter + 1
END
SET #SQL=#SQL+')'
print #SQL
drop table #inVars
drop table #Test
It is not very clear what you want here but I think you are making it harder on yourself than you need to. There is no need to use the IN because you are also finding all values that begin with the same value. And you have hard coded the same values into your temp table. Using a string splitter this is about a million times less complicated. Just split your #OriginID on the commas and use LIKE in the join.
I am using the DelimitedSplit8k which you can find here
I am pretty sure this should get you the information you are looking for. I would recommend avoiding loops whenever possible.
create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values ('5','31'),
('5','31_00000'),
('5','33'),
('5','33_00000'),
('5','25'),
('5','25_00000'),
('5','HD_00000'),
('5','HD')
DECLARE
#OrganizationId int = 5,
#OriginId nvarchar(256) = N'31,25,33'
select *
from #Test t
join DelimitedSplit8K(#OriginID, ',') x on t.OrigID like x.Item + '%'
drop table #Test
I solved this.Thanks all who replied.
create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values ('5','31'),
('5','31_00000'),
('5','33'),
('5','33_00000'),
('5','25'),
('5','25_00000'),
('5','HD_00000'),
('5','HD')
DECLARE
#OrganizationId int = 5,
#OriginId nvarchar(256) = N'31,25,33'
create table #inVars(id int NOT NULL IDENTITY PRIMARY KEY, origins varchar(256))
insert into #inVars(origins)
Values ('31'),
('33'),
('25')
DECLARE #SQL NVARCHAR(MAX),
#ParamDefinition NVARCHAR(MAX)
SET #ParamDefinition = N'#OrganizationId int,
#OriginId nvarchar(256)'
SET #SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=#OrganizationId'
IF ISNULL(#OriginId,'') <> ''
BEGIN
SET #SQL = #SQL +' AND (OrigID in (''' + #OriginId + ''')) '
END
IF ISNULL(#OriginId,'') <> ''
DECLARE #counter INT = 1, #max INT = 0, #Origin nvarchar(50), #SQL_2 nvarchar(max)
SELECT #max = COUNT(id) FROM #inVars
WHILE #counter <= #max
BEGIN
SET #Origin = (select origins from #invars where id = CAST(#counter as varchar(10)))
SET #Origin = #Origin+'_%'
SET #SQL_2 = N' OR (OrigID LIKE ''' + #Origin + ''') '
SET #SQL = #SQL + #SQL_2
SET #counter = #counter + 1
END
print(#SQL)
EXEC sp_executesql #SQL,#ParamDefinition,#OrganizationId,#OriginId
drop table #inVars
drop table #Test

SQL - Remove (Eliminate) columns which have no data

I wonder that;
in SQl, is it possible to not bring the columns which have no data (or zero value)?
Select * from PLAYER_TABLE where PLAYER_NAME='cagri'
it is bringing just 1 row. because there is only one player which PLAYER_NAME is "cagri".
And there are 30 columns for example statistics.
Score-Rebound-PlayedMinutes-Fauls etc....
Score=2
Rebound=0
PlayedMinutes=2
Fauls=0
and I want to see only [Score] and [PlayedMinutes] columns when call my query.
is it possible?
You can use this logic over a stored procedure in SQL
DDL
create table usr_testtable
(player varchar(30),col1 float, col2 float, col3 float, col4 float)
insert into usr_testtable
values ('Jordan',10,20,3,0)
Convert to Stored Proc
declare #playername varchar(30) = 'Jordan' --- pass this value
declare #ctr smallint = 2 -- start from ordinal 2
declare #maxctr smallint = (SELECT max(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'usr_testTable')
declare #columns varchar(max) = ''
declare #columnswithvalues varchar(max) = ''
declare #coltocheck varchar(30)
declare #mysql nvarchar(max)
declare #coloutput varchar(30)
while #ctr <= #maxctr
begin
SELECT #coltocheck = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'usr_testTable'
and ORDINAL_POSITION = #ctr
set #mysql = N'select #output = ' + #coltocheck + ' from usr_testTable where player =''' + #playername + ''' and cast(' + #coltocheck +' as float) > 0'
EXECUTE sp_executesql #mysql,N'#output int OUTPUT',#output = #coloutput OUTPUT;
if #coloutput > 0
begin
set #columns = coalesce(#columns + ',' + #coltocheck,#columns)
set #columnswithvalues = coalesce(#columnswithvalues + char(13) + char(10) + #coltocheck + ' : ' + #coloutput,#columnswithvalues) --- text form
end
set #coloutput = ''
set #ctr= #ctr + 1
end
-- final result in table format
set #mysql = N'select player' + #columns + ' from usr_testTable where player =''' + #playername + ''' '
EXECUTE sp_executesql #mysql
-- final result in text format appended with columnname
select #columnswithvalues -- format to display in text
First create dynamic SQL to select all columns names in the table PLAYER_TABLE except PLAYER_NAME, then unpivot data from PLAYER_TABLE into table PLAYER_TABLE1, then you can search values <> 0 and select this column in second dynamic SQL.
DROP TABLE PLAYER_TABLE1
DECLARE #Player NVARCHAR(50);
DECLARE #columns NVARCHAR(max);
DECLARE #sql NVARCHAR(max);
DECLARE #columns2 NVARCHAR(max);
DECLARE #sql2 NVARCHAR(max);
SET #player='cagri'
SET #columns = Stuff((SELECT ','
+ Quotename(Rtrim(Ltrim(x.columns)))
FROM (SELECT COLUMN_NAME as columns FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= 'PLAYER_TABLE' and COLUMN_NAME<>'PLAYER_NAME' ) AS x
ORDER BY X.columns
FOR xml path('')), 1, 1, '');
SET #sql = N' SELECT
PLAYER_NAME, Un_Pivot.Field, Un_Pivot.Value
INTO PLAYER_TABLE1
FROM
(
SELECT * FROM PLAYER_TABLE
) Data
UNPIVOT
(
Value FOR Field IN ('+#columns+')
) AS Un_Pivot';
EXECUTE sp_executesql #sql;
SET #columns2 = Stuff((SELECT ','
+ Quotename(Rtrim(Ltrim(y.Field)))
FROM (SELECT Field FROM PLAYER_TABLE1 WHERE VALUE<>0 AND PLAYER_NAME=#Player) AS y
ORDER BY y.Field
FOR xml path('')), 1, 1, '');
SET #sql2 = N'SELECT PLAYER_NAME,'+#columns2+'FROM PLAYER_TABLE WHERE PLAYER_NAME='+char(39)+#Player+char(39);
EXECUTE sp_executesql #sql2

WITH statement in dynamic sql

I need to store a query as a stored procedure in SQL Server.
I need also to pass parameters which define tablenames and column names.
This is the query I owuld like to have, I tried to store it in a string and then EXECUTE it but without success, ho can I solve this?
CREATE PROCEDURE sp_selectAllParents #id int, #tableid varchar(30), #tablename varchar(30)
AS BEGIN
SET NOCOUNT ON;
WITH ct AS (
SELECT * FROM #tablename t WHERE #tableid = #id
UNION ALL
SELECT t.* FROM #tablename t JOIN ct ON t.parentId = ct.#tableid
)
SELECT * FROM #tablename t WHERE #tableid NOT IN (SELECT #tableid FROM ct)
END
EDIT:
my attempt was:
DECLARE #sql varchar(255)
SET #sql = 'WITH ct AS (SELECT * FROM #tablename t WHERE #tableid = #id UNION ALL SELECT t.* FROM #tablename t JOIN ct ON t.parentId = ct.#tableid) SELECT * FROM #tablename t WHERE #tableid NOT IN (SELECT #tableid FROM ct)'
EXEC(#sql)
As I already in the comment section, it is a bad idea to do this. You should really rethink your solution.
The Stored Procedure would have to look like this:
CREATE PROCEDURE selectAllParents #id int, #tableid sysname, #tablename sysname
AS
BEGIN
SET NOCOUNT ON;
-- Guards against SQL Injection attacks (replace ' with '')
SET #tableid=REPLACE(#tableid,'''','''''');
SET #tablename=REPLACE(#tablename,'''','''''');
DECLARE #stmt NVARCHAR(4000);
SET #stmt=
';WITH ct AS ('+
'SELECT * FROM ' + QUOTENAME(#tablename) + ' t WHERE ' + QUOTENAME(#tableid) + '= #id ' +
'UNION ALL ' +
'SELECT t.* FROM ' + QUOTENAME(#tablename) + ' t JOIN ct ON t.parentId = ct.' + QUOTENAME(#tableid) +
')'+
'SELECT * FROM ' + QUOTENAME(#tablename) +' t WHERE ' + QUOTENAME(#tableid) + ' NOT IN (SELECT ' + QUOTENAME(#tableid) +' FROM ct);';
EXEC sp_executesql
#stmt,
N'#id int',
#id;
END
GO
if your are sending Table name as parameter in that case you need to create dynamic query string. may help below script
CREATE PROCEDURE sp_selectAllParents #id int, #tableid varchar(30), #tablename varchar(30)
AS BEGIN
SET NOCOUNT ON;
SET #query=N'WITH ct AS (
SELECT * FROM #tablename t WHERE #tableid = #id
UNION ALL
SELECT t.* FROM #tablename t JOIN ct ON t.parentId = ct.#tableid
)
SELECT * FROM #tablename t WHERE #tableid NOT IN (SELECT #tableid FROM ct)'
EXECUTE sp_executesql #query, #id,#tablename,#tableid
END

SQL Server PRINT SELECT (Print a select query result)?

I am trying to print a selected value, is this possible?
Example:
PRINT
SELECT SUM(Amount) FROM Expense
You know, there might be an easier way but the first thing that pops to mind is:
Declare #SumVal int;
Select #SumVal=Sum(Amount) From Expense;
Print #SumVal;
You can, of course, print any number of fields from the table in this way. Of course, if you want to print all of the results from a query that returns multiple rows, you'd just direct your output appropriately (e.g. to Text).
If you're OK with viewing it as XML:
DECLARE #xmltmp xml = (SELECT * FROM table FOR XML AUTO)
PRINT CONVERT(NVARCHAR(MAX), #xmltmp)
While the OP's question as asked doesn't necessarily require this, it's useful if you got here looking to print multiple rows/columns (within reason).
If you want to print multiple rows, you can iterate through the result by using a cursor.
e.g. print all names from sys.database_principals
DECLARE #name nvarchar(128)
DECLARE cur CURSOR FOR
SELECT name FROM sys.database_principals
OPEN cur
FETCH NEXT FROM cur INTO #name;
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #name
FETCH NEXT FROM cur INTO #name;
END
CLOSE cur;
DEALLOCATE cur;
set #n = (select sum(Amount) from Expense)
print 'n=' + #n
I wrote this SP to do just what you want, however, you need to use dynamic sql.
This worked for me on SQL Server 2008 R2
ALTER procedure [dbo].[PrintSQLResults]
#query nvarchar(MAX),
#numberToDisplay int = 10,
#padding int = 20
as
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
declare #cols nvarchar(MAX),
#displayCols nvarchar(MAX),
#sql nvarchar(MAX),
#printableResults nvarchar(MAX),
#NewLineChar AS char(2) = char(13) + char(10),
#Tab AS char(9) = char(9);
if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable
set #query = REPLACE(#query, 'from', ' into ##PrintSQLResultsTempTable from');
--print #query
exec(#query);
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable
from ##PrintSQLResultsTempTable
drop table ##PrintSQLResultsTempTable
select name
into #PrintSQLResultsTempTableColumns
from tempdb.sys.columns where object_id =
object_id('tempdb..#PrintSQLResultsTempTable');
select #cols =
stuff((
(select ' + space(1) + (LEFT( (CAST([' + name + '] as nvarchar(max)) + space('+ CAST(#padding as nvarchar(4)) +')), '+CAST(#padding as nvarchar(4))+')) ' as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'''''');
select #displayCols =
stuff((
(select space(1) + LEFT(name + space(#padding), #padding) as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'');
DECLARE
#tableCount int = (select count(*) from #PrintSQLResultsTempTable);
DECLARE
#i int = 1,
#ii int = case when #tableCount < #numberToDisplay then #tableCount else #numberToDisplay end;
print #displayCols -- header
While #i <= #ii
BEGIN
set #sql = N'select #printableResults = ' + #cols + ' + #NewLineChar from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(#i as varchar(3)) + '; print #printableResults;'
--print #sql
execute sp_executesql #sql, N'#NewLineChar char(2), #printableResults nvarchar(max) output', #NewLineChar = #NewLineChar, #printableResults = #printableResults output
print #printableResults
SET #i += 1;
END
This worked for me on SQL Server 2012
ALTER procedure [dbo].[PrintSQLResults]
#query nvarchar(MAX),
#numberToDisplay int = 10,
#padding int = 20
as
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
declare #cols nvarchar(MAX),
#displayCols nvarchar(MAX),
#sql nvarchar(MAX),
#printableResults nvarchar(MAX),
#NewLineChar AS char(2) = char(13) + char(10),
#Tab AS char(9) = char(9);
if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable
set #query = REPLACE(#query, 'from', ' into ##PrintSQLResultsTempTable from');
--print #query
exec(#query);
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable
from ##PrintSQLResultsTempTable
drop table ##PrintSQLResultsTempTable
select name
into #PrintSQLResultsTempTableColumns
from tempdb.sys.columns where object_id =
object_id('tempdb..#PrintSQLResultsTempTable');
select #cols =
stuff((
(select ' + space(1) + LEFT(CAST([' + name + '] as nvarchar('+CAST(#padding as nvarchar(4))+')) + space('+ CAST(#padding as nvarchar(4)) +'), '+CAST(#padding as nvarchar(4))+') ' as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'''''');
select #displayCols =
stuff((
(select space(1) + LEFT(name + space(#padding), #padding) as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'');
DECLARE
#tableCount int = (select count(*) from #PrintSQLResultsTempTable);
DECLARE
#i int = 1,
#ii int = case when #tableCount < #numberToDisplay then #tableCount else #numberToDisplay end;
print #displayCols -- header
While #i <= #ii
BEGIN
set #sql = N'select #printableResults = ' + #cols + ' + #NewLineChar from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(#i as varchar(3)) + ' '
--print #sql
execute sp_executesql #sql, N'#NewLineChar char(2), #printableResults nvarchar(max) output', #NewLineChar = #NewLineChar, #printableResults = #printableResults output
print #printableResults
SET #i += 1;
END
This worked for me on SQL Server 2014
ALTER procedure [dbo].[PrintSQLResults]
#query nvarchar(MAX),
#numberToDisplay int = 10,
#padding int = 20
as
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
declare #cols nvarchar(MAX),
#displayCols nvarchar(MAX),
#sql nvarchar(MAX),
#printableResults nvarchar(MAX),
#NewLineChar AS char(2) = char(13) + char(10),
#Tab AS char(9) = char(9);
if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable
set #query = REPLACE(#query, 'from', ' into ##PrintSQLResultsTempTable from');
--print #query
exec(#query);
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable
from ##PrintSQLResultsTempTable
drop table ##PrintSQLResultsTempTable
select name
into #PrintSQLResultsTempTableColumns
from tempdb.sys.columns where object_id =
object_id('tempdb..#PrintSQLResultsTempTable');
select #cols =
stuff((
(select ' , space(1) + LEFT(CAST([' + name + '] as nvarchar('+CAST(#padding as nvarchar(4))+')) + space('+ CAST(#padding as nvarchar(4)) +'), '+CAST(#padding as nvarchar(4))+') ' as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'''''');
select #displayCols =
stuff((
(select space(1) + LEFT(name + space(#padding), #padding) as [text()]
FROM #PrintSQLResultsTempTableColumns
where name != 'ID12345XYZ'
FOR XML PATH(''), root('str'), type ).value('/str[1]','nvarchar(max)'))
,1,0,'');
DECLARE
#tableCount int = (select count(*) from #PrintSQLResultsTempTable);
DECLARE
#i int = 1,
#ii int = case when #tableCount < #numberToDisplay then #tableCount else #numberToDisplay end;
print #displayCols -- header
While #i <= #ii
BEGIN
set #sql = N'select #printableResults = concat(#printableResults, ' + #cols + ', #NewLineChar) from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(#i as varchar(3))
--print #sql
execute sp_executesql #sql, N'#NewLineChar char(2), #printableResults nvarchar(max) output', #NewLineChar = #NewLineChar, #printableResults = #printableResults output
print #printableResults
SET #printableResults = null;
SET #i += 1;
END
Example:
exec [dbo].[PrintSQLResults] n'select * from MyTable'
Try this query
DECLARE #PrintVarchar nvarchar(max) = (Select Sum(Amount) From Expense)
PRINT 'Varchar format =' + #PrintVarchar
DECLARE #PrintInt int = (Select Sum(Amount) From Expense)
PRINT #PrintInt
If you want to print more than a single result, just select rows into a temporary table, then select from that temp table into a buffer, then print the buffer:
drop table if exists #temp
-- we just want to see our rows, not how many were inserted
set nocount on
select * into #temp from MyTable
-- note: SSMS will only show 8000 chars
declare #buffer varchar(MAX) = ''
select #buffer = #buffer + Col1 + ' ' + Col2 + CHAR(10) from #temp
print #buffer
Add
PRINT 'Hardcoded table name -' + CAST(##RowCount as varchar(10))
immediately after the query.
You can also use the undocumented sp_MSforeachtable stored procedure as such if you are looking to do this for every table:
sp_MSforeachtable #command1 ="PRINT 'TABLE NAME: ' + '?' DECLARE #RowCount INT SET #RowCount = (SELECT COUNT(*) FROM ?) PRINT #RowCount"
If you wish (like me) to have results containing mulitple rows of various SELECT queries "labelled" and can't manage this within the constraints of the PRINT statement in concert with the Messages tab you could turn it around and simply add messages to the Results tab per the below:
SELECT 'Results from scenario 1'
SELECT
*
FROM tblSample
Try this:
DECLARE #select as nvarchar(max) = ''
SELECT #select = #select + somefield + char(13) FROM sometable
PRINT #select

Resources