HOW TO SELECT FROM EXEC sp_executeSql? - sql-server

My stored procedures:
#currPage int,
#recodperpage int,
#name varchar(20) = NULL,
#type varchar(50) = NULL,
#size varchar(50) = NULL,
#country varchar(50) = NULL
AS
BEGIN
DECLARE #Sql NVARCHAR(MAX);
SELECT
#Sql = N'SELECT ROW_NUMBER()
OVER(ORDER BY MatchID Desc) AS RowNum,
MatchID,
NameMatch,
Images
FROM Match WHERE MatchID > 0 '
IF #type IS NOT NULL
SELECT #Sql += N' AND Type = ''' + REPLACE(convert(varchar(50),#type),'''','''''')+'''';
IF #size IS NOT NULL
SELECT #Sql += N' AND MatchSize = ''' + REPLACE(convert(varchar(50),#size),'''','''''')+'''';
IF #country IS NOT NULL
SELECT #Sql += N' AND Country = ''' + REPLACE(convert(varchar(50),#country),'''','''''')+''''
EXEC SP_EXECUTESQL #Sql
END
I want to
select *
from EXEC SP_EXECUTESQL #Sql result
where RowNum between (#currPage - 1) * #recodperpage + 1
and #currPage * #recodperpage

You can declare a #table with same columns as in stored procedure output and then:
INSERT INTO #table
EXEC SP_EXECUTESQL #Sql
SELECT *
FROM #table
where RowNum between (#currPage - 1) * #recodperpage + 1
and #currPage * #recodperpage

I guess you can parametrize your where clause in dynamic query
DECLARE #Sql NVARCHAR(MAX),
#currPage INT,
#recodperpage INT
SELECT #Sql = N'select * from(SELECT ROW_NUMBER()
OVER(ORDER BY MatchID Desc) AS RowNum,
MatchID,
NameMatch,
Images
FROM Match WHERE MatchID > 0 '
IF #type IS NOT NULL
SELECT #Sql += N' AND Type = '''
+ Replace(CONVERT(VARCHAR(50), #type), '''', '''''')
+ '''';
IF #size IS NOT NULL
SELECT #Sql += N' AND MatchSize = '''
+ Replace(CONVERT(VARCHAR(50), #size), '''', '''''')
+ '''';
IF #country IS NOT NULL
SELECT #Sql += N' AND Country = '''
+ Replace(CONVERT(VARCHAR(50), #country), '''', '''''')
+ ''''
SELECT #sql += ' ) A where RowNum between (#currPage - 1) * #recodperpage + 1
and #currPage * #recodperpage'
EXEC Sp_executesql
#Sql,
N'#currPage int,#recodperpage int',
#currPage =#currPage,
#recodperpage =#recodperpage

Related

How can I turn this dynamic query into a procedure or function?

I have a dynamic query that pulls from a list of tables with the names of those stored in another table but I would like to be able to use the resulting set in another query.
declare #t table( tablename varchar(50))
declare #sql varchar(max)
set #sql = ''
insert into #t
SELECT t.svc_table AS table_name FROM svc_defs AS t
SELECT #sql = #sql + 'Select convert(varchar(5),svc_defs.svc_id) as svcid, data_id, crid, d_custid, d_active From ' + tablename +
' inner join svc_defs on svc_defs.svc_table = ' + '''' + tablename + '''' + ' union ' from #t
--remove the trailing 'union'
Select #sql = substring(#sql, 1, len(#sql) - 6)
exec (#sql)
You can create scalar user defined function, which returns the sql statement.
CREATE FUNCTION dbo.udf_GenerateSelectQuery()
Returns nvarchar(max)
AS
BEGIN
declare #t table( tablename SYSNAME)
declare #sql Nvarchar(max)
set #sql = ''
insert into #t
SELECT t.TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES AS t
SELECT #sql = #sql + 'Select convert(varchar(5),svc_defs.svc_id) as svcid, data_id, crid, d_custid, d_active From ' + tablename +
' inner join svc_defs on svc_defs.svc_table = ' + '''' + tablename + '''' + ' union ' from #t
--remove the trailing 'union'
Select #sql = substring(#sql, 1, len(#sql) - 6)
RETURN #sql
END
you can call it as
declare #sqlstmt NVARCHAR(max) = dbo.udf_GenerateSelectQuery()
SELECT #sqlstmt
or as
declare #sqlstmt NVARCHAR(max)
SET #sqlstmt = (SELECT dbo.udf_GenerateSelectQuery())
SELECT #sqlstmt

Dynamic SQL Query to find the count of missing values for all column of a table

I want to write a dynamic sql query to find out the count of missing value for each column from a table. The table comprises of 40 columns and writing missing count for each column is lengthy so can we do it dynamically? I tried to write dynamic query as provided below, but got an error as
Must declare the scalar variable "#sql"
Query:
Declare #sql nvarchar(max)
Declare #columnlist nvarchar(max)
Declare #FieldName nvarchar(max)
set #columnlist = 'Column 1,Column2 ,Column3 ,Column4 ,Column5 ,Column6 ,Column7 ,Column8 ,Column9 ,Column10 ,Column11 ,Column12,Column13'
set #FieldName = 'Column 1,Column2 ,Column3 ,Column4 ,Column5 ,Column6 ,Column7 ,Column8 ,Column9 ,Column10 ,Column11 ,Column12,Column13'
set #sql = 'SELECT COUNT(*)-COUNT(' + #columnlist + ') as '+ #FieldName +'from table_name'
exec (#sql)
Try this:
DECLARE #sql nvarchar(max) = N'SELECT';
DECLARE #table_name nvarchar(256) = N'YourTableName'
SELECT #sql = #sql + ' COUNT(*)-COUNT(' + QUOTENAME(COLUMN_NAME) + ') as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
AND TABLE_NAME = #table_name
SET #sql = LEFT(#sql, LEN(#sql) - 1) + ' from ' + #table_name
EXEC (#sql)
Added
Allright, so here's an example on how to use something alike to for each column calculate the number of values that have at least one duplicate:
DECLARE #sql nvarchar(max) = N'WITH duplicates AS (SELECT';
DECLARE #table_name nvarchar(256) = N'YourTableName';
SELECT #sql = #sql
+ N' CASE WHEN COUNT(' + QUOTENAME(COLUMN_NAME)
+ N') OVER (PARTITION BY ' + QUOTENAME(COLUMN_NAME)
+ N') > 1 THEN ' + QUOTENAME(COLUMN_NAME)
+ N' END as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
AND TABLE_NAME = #table_name;
SET #sql = LEFT(#sql, LEN(#sql) - 1) + ' from ' + #table_name + ') SELECT';
SELECT #sql = #sql
+ N' COUNT(DISTINCT ' + QUOTENAME(COLUMN_NAME)
+ N') as '+ QUOTENAME(COLUMN_NAME) + N','
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
AND TABLE_NAME = #table_name;
SET #sql = LEFT(#sql, LEN(#sql) - 1) + ' from duplicates';
EXEC (#sql);
You see that it uses 2 SELECT statements, the first creates a CTE that replaces all values that have no duplicate with NULL:
CASE WHEN COUNT([C1]) OVER (PARTITION BY [C1]) > 1 THEN [C1] END as [C1]
The second uses a COUNT DISTINCT to count what is left. Doing it this way, the value NULL will not be counted.
Try this
IF OBJECT_ID('TempDb..#MissingList') IS NOT NULL
DROP TABLE #MissingList
CREATE TABLE #MissingList
(
SeqNo INT IDENTITY(1,1),
TABLE_NAME VARCHAR(255),
COLUMN_NAME VARCHAR(255),
MissingCount INT DEFAULT(0)
)
DECLARE #SQL NVARCHAR(MAX)
SELECT
#SQL = REPLACE(REPLACE(L.List,'&#x0D',''),';','')
FROM
(
SELECT
'
INSERT INTO #MissingList(TABLE_NAME,COLUMN_NAME,MissingCount)
SELECT TABLE_NAME = ''['+LTRIM(RTRIM(TABLE_SCHEMA))+'].['+LTRIM(RTRIM(TABLE_NAME))+']'',COLUMN_NAME = '''+LTRIM(RTRIM(COLUMN_NAME))+''',MissingCount = COUNT(1) - COUNT(['+LTRIM(RTRIM(COLUMN_NAME))+'])
FROM ['+LTRIM(RTRIM(TABLE_SCHEMA))+'].['+LTRIM(RTRIM(TABLE_NAME))+']' AS [text()]
FROM INFORMATION_SCHEMA.COLUMNS
FOR XML PATH('')
)L(LIST)
EXEC(#SQL)
SELECT
*
FROM #MissingList

Can you return the results a query from table and Fields returned in a query

The following is the results of a query used to Search Columns
DECLARE #Temp TABLE (
[CoreTable] VARCHAR(250),
[CoreTableDecription] VARCHAR(250),
[FieldName] VARCHAR(250),
[cnt] VARCHAR(250)
)
declare #Keyword1 VARCHAR(100) = '%Prob%'
declare #Keyword2 VARCHAR(100) = '%Prob%'
--------------------------------------------------------------
INSERT INTO #Temp (CoreTable, CoreTableDecription, FieldName, cnt)
VALUES
('PRO','PROTOS_PersonalInformation','AnyCommunicationProblem','1'),
('PRO','PROTOS_PersonalInformation','SightProblems','1'),
('PRO','PROTOS_PersonalInformation','SpeechProblems','1'),
('PRO','PROTOSMODEL_Antenatal_Status','Other_Antenatal_Problems','1'),
('PRO','PROTOSMODEL_Antenatal_Status','Other_Antenatal_Problems_Text','1'),
('PRO','PROTOSMODEL_Baby_Details','Neonatal_medical_problems','1'),
('PRO','PROTOSMODEL_Baby_Details','Neonatal_medical_problems_Text','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Bruising','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Naevus','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Rash','1'),
('PRO','PROTOSMODEL_Baby_Postnatal','Any_skin_problems_detected_Text','1')
Select * from #Temp
This is great for finding/search and the query used is below
declare #Keyword1 VARCHAR(100) = '%Prob%'
declare #Keyword2 VARCHAR(100) = '%Prob%'
select
LEFT(o.name,3) CoreTable,
o.name CoreTableDesc,
--o.name AS TableName,
c.name AS FieldName
,COUNT(c.name) cnt
from sys.columns c
inner join sys.objects o on c.object_id=o.object_id
where c.name LIKE #Keyword1
and LEFT(o.name,3) in ('PRO')
and c.name LIKE #Keyword2
GROUP BY c.name, LEFT(o.name,3), o.name
-- order by LEFT(o.name,3), c.name
However what I then need to do is run a manual query to determine the values in the columns/tables (see below):
select AnyCommunicationProblem, count(*) cnt
from PROTOS_PersonalInformation
GROUP BY AnyCommunicationProblem
This returns simplythe rows NULL - 2682, No - 87687, Yes - 135478
I'm wondering if there is a way to do this automatically from the results of the first query which display the Table name and Column names
Thanks all the answer was below but I was unsure how to get the count if the data items in
DECLARE
#TABLENAME VARCHAR(255),
#FIELDNAME VARCHAR(255),
#SQL VARCHAR(MAX),
#FieldNamePart1 as varchar(50),
#FieldNamePart2 as varchar(50)
SET #SQL = ''
SET #FieldNamePart1 = 'Type'
SET #FieldNamePart2 = 'Method'
IF #FieldNamepart2 = ''
DECLARE CRS CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE CHARINDEX('PROTOSMODEL',TABLE_NAME) <> 0
AND CHARINDEX(#FieldNamePart1, COLUMN_NAME) <> 0
-- AND CHARINDEX('DATE', COLUMN_NAME) = 0
-- AND CHARINDEX('TIME', COLUMN_NAME) = 0
ELSE
DECLARE CRS CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE CHARINDEX('PROTOSMODEL',TABLE_NAME) <> 0
AND CHARINDEX(#FieldNamePart1, COLUMN_NAME) <> 0
AND CHARINDEX(#FieldNamePart2, COLUMN_NAME) <> 0
-- AND CHARINDEX('DATE', COLUMN_NAME) = 0
-- AND CHARINDEX('TIME', COLUMN_NAME) = 0
OPEN CRS
FETCH NEXT FROM CRS INTO #TABLENAME, #FIELDNAME
WHILE ##FETCH_STATUS = 0
BEGIN
-- SET #SQL = #SQL + CAST('SELECT DISTINCT ''' AS VARCHAR(MAX)) + CAST(#TABLENAME AS VARCHAR(MAX)) + CAST(''' AS PROTOSMODEL_TABLE, ''' AS VARCHAR(MAX)) + CAST(#FIELDNAME AS VARCHAR(MAX)) + CAST(''' AS PROTOSMODEL_FIELD, ' AS VARCHAR(MAX)) + CAST(#FIELDNAME AS VARCHAR(MAX)) + CAST(' AS FIELD_VALUE FROM ' AS VARCHAR(MAX)) + CAST(#TABLENAME AS VARCHAR(MAX)) + CAST(' UNION ALL ' AS VARCHAR(MAX))
SET #SQL = #SQL + 'SELECT DISTINCT ''' + #TABLENAME + ''' AS PROTOSMODEL_TABLE, ''' + #FIELDNAME + ''' AS PROTOSMODEL_FIELD, [' + #FIELDNAME + '] AS FIELD_VALUE FROM ' + #TABLENAME + ' UNION ALL '
FETCH NEXT FROM CRS INTO #TABLENAME, #FIELDNAME
END
CLOSE CRS
DEALLOCATE CRS
SET #SQL = SUBSTRING(#SQL, 1, LEN(#SQL) - 10)
EXEC (#SQL)
GO

SQL Server : dynamic query

I have a SQL Server 2008 with a table that acts like a hash-map. basically, there's three columns (id, key, val) and I need to pull the other columns a, b, c, d, e.
The purpose is to basically choose the database I need to query data from. Similar to this issue Using the correct database
I have got the SQL using a brute force method. I'm just trying do this in a better, more efficient way
Here's the SQL I'm trying to get to work:
CREATE PROCEDURE [dbo].[me]
#partitionName VARCHAR(64),
#id INT
AS
BEGIN
SET NOCOUNT ON
SET ROWCOUNT 0
DECLARE #table as varchar(128)
DECLARE #sql as nvarchar(4000)
DECLARE #params as nvarchar(4000)
DECLARE #s_key as varchar(64)
DECLARE #paramDefinition as nvarchar(4000)
DECLARE #a INT
DECLARE #b VARCHAR(32)
DECLARE #c VARCHAR(32)
DECLARE #d VARCHAR(32)
DECLARE #e VARCHAR(32)
SET #table = #partitionName + '.dbo.hash_table'
SET #sql =
N'SELECT ' +
N' #a = MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END),
#b = MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END),
#c = MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END),
#d = MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END),
#e = MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END)
FROM ' + #table +
N'WHERE id = ' + CONVERT(VARCHAR(3), #id)
EXEC sp_executesql #sql
But, this gives the following error
Must declare the scalar variable "#a"
I have a feeling I need to do something like pass in #paramsDefinition to sp_executesql
But so far, these have failed
SET #paramDefinition = '#a INT OUTPUT, '
+ ' #b varchar(32) OUTPUT, '
+ ' #c varchar(32) OUTPUT, '
+ ' #d varchar(32) OUTPUT,'
+ ' #r varchar(32) OUTPUT'
...
EXEC sp_executesql #sql, #paramDefintions
I get
Incorrect syntax near '='.
Here is the brute force method (which works but hits the DB 5 times)
SET #key = 'a'
SET #sql =
N' SELECT #a = val FROM ' + #table +
N' WHERE key = ' + quotename(#key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), #nid)
EXEC sp_executesql #sql, N'#a varchar(32) OUTPUT', #a = #a OUTPUT
SET #key = 'b'
SET #sql =
N' SELECT #b = val FROM ' + #table +
N' WHERE key = ' + quotename(#key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), #id)
EXEC sp_executesql #sql, N'#b varchar(32) OUTPUT', #b = #b OUTPUT
SET #key = 'c'
SET #sql =
N' SELECT #c = val FROM ' + #table +
N' WHERE key = ' + quotename(#key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), #id)
EXEC sp_executesql #sql, N'#c varchar(32) OUTPUT', #c = #c OUTPUT
SET #key = 'd'
SET #sql =
N' SELECT #d = val FROM ' + #table +
N' WHERE key = ' + quotename(#key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), #id)
EXEC sp_executesql #sql, N'#d varchar(32) OUTPUT', #d = #d OUTPUT
SET #key = 'e'
SET #sql =
N' SELECT #e = val FROM ' + #table +
N' WHERE key = ' + quotename(#key, '''') +
N' AND id = ' + CONVERT(VARCHAR(3), #id)
EXEC sp_executesql #sql, N'#e varchar(32) OUTPUT', #e = #e OUTPUT
SELECT #a as [a], #b as [b], #c as [c], #d as [d], #r as [r]
You can try to use a temporary table like this:
CREATE PROCEDURE [dbo].[me]
#partitionName VARCHAR(64),
#id INT
AS
BEGIN
SET NOCOUNT ON
SET ROWCOUNT 0
DECLARE #table as varchar(128)
DECLARE #sql as nvarchar(4000)
DECLARE #params as nvarchar(4000)
DECLARE #s_key as varchar(64)
DECLARE #paramDefinition as nvarchar(4000)
DECLARE #a INT
DECLARE #b VARCHAR(32)
DECLARE #c VARCHAR(32)
DECLARE #d VARCHAR(32)
DECLARE #e VARCHAR(32)
SET #table = #partitionName + '.dbo.hash_table'
CREATE TABLE #tmp (code varchar(50))
SET #sql =
N'SELECT ' +
N' MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END) as [a],
MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END) as [b],
MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END) as [c],
MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END) as [d],
MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END) as [e]
FROM ' + #table +
N'WHERE id = ' + CONVERT(VARCHAR(3), #id)
INSERT INTO #tmp (code)
EXEC sp_executesql #sql
SELECT * from #tmp
Hope it helps.
Try this.....
Dynamic SQL has its own scope, Variables in your stored procedure arent visible to to your dynamic sql, you will need to declare these variables as second parameter to sp_execuetsql and since you are reverting values back in these variables, you will need to use key word OUTPUT with these variables when passing them to sp_executesql , as follows
CREATE PROCEDURE [dbo].[me]
#partitionName SYSNAME,
#id INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #table as varchar(128)
DECLARE #sql as nvarchar(4000)
DECLARE #params as nvarchar(4000)
DECLARE #s_key as varchar(64)
DECLARE #paramDefinition as nvarchar(4000)
DECLARE #a INT
DECLARE #b VARCHAR(32)
DECLARE #c VARCHAR(32)
DECLARE #d VARCHAR(32)
DECLARE #e VARCHAR(32)
SET #table = #partitionName + 'hash_table'
SET #sql = N'SELECT ' +
N' #a = MAX(CASE WHEN [key] = ''a'' THEN value ELSE '''' END),
#b = MAX(CASE WHEN [key] = ''b'' THEN value ELSE '''' END),
#c = MAX(CASE WHEN [key] = ''c'' THEN value ELSE '''' END),
#d = MAX(CASE WHEN [key] = ''d'' THEN value ELSE '''' END),
#e = MAX(CASE WHEN [key] = ''e'' THEN value ELSE '''' END)
FROM dbo.' + QUOTENAME(#table) +
N' WHERE id = #id)'
EXEC sp_executesql #sql
,N'#a INT OUTPUT, #b VARCHAR(32) OUTPUT,#b VARCHAR(32) OUTPUT,#c VARCHAR(32) OUTPUT,
#d VARCHAR(32) OUTPUT,#e VARCHAR(32) OUTPUT, #id INT'
,#a OUTPUT
,#b OUTPUT
,#c OUTPUT
,#d OUTPUT
,#e OUTPUT
,#id
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