Related
I would like to create a temptable that will hold the result of this query:
set #sql = 'use ' + #dbname + '; select db_name() , name from sys.tables where is_ms_shipped = 0 and type_desc = ''USER_TABLE'' '
exec (#sql)
Here is the full query I have:
declare #minx int = 0
declare #maxx int = (select max(id) from #DBS)
declare #sql nvarchar(1000)
declare #dbname varchar (130)
declare #count int
Select *
from #DBS
while (#count is not null
and #count <= #maxx)
begin
select #dbname = dbname
from #DBS where id = #count
print 'id = ' + convert (varchar, #count) + ' dbname = ' + #dbname
set #sql = 'use ' + #dbname + '; select db_name() , name from sys.tables where is_ms_shipped = 0 and type_desc = ''USER_TABLE'' '
exec (#sql)
set #count = #count + 1
break
end;
I have tried so many things and always getting error messages.
Anybody could give me an insight?
Not sure how you populate #DBS but:
CREATE TABLE #tables(db sysname, table_name sysname);
DECLARE #dbs cursor,
#context nvarchar(1000),
#sql nvarchar(max);
SET #sql = N'INSERT #tables(db, table_name)
SELECT DB_NAME(), name
FROM sys.tables
WHERE type = ''U'' AND is_ms_shipped = 0;';
SET #dbs = CURSOR FOR SELECT QUOTENAME(dbname)
+ N'.sys.sp_executesql' FROM #DBS;
OPEN #dbs;
FETCH NEXT FROM #dbs INTO #context;
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE #context #sql;
FETCH NEXT FROM #dbs INTO #context;
END
SELECT db, table_name FROM #tables;
Also see this related question.
Just wondering any one can help me with this T-SQL script, error code below. As my expertise in SQL is very limited I am not sure if this means that store procedure is missing or something actually wrong with the script.
EXEC isp_ALTER_INDEX
#dbName = 'MODEV',
#statsMode = 'SAMPLED',
#defragType = 'REBUILD',
#minFragPercent = 5,
#maxFragPercent = 100,
#minRowCount = 1000000,
#logHistory = 1,
#sortInTempdb = 1
Error
Executed as user: Could not find stored procedure 'isp_ALTER_INDEX'. [SQLSTATE 42000] (Error 2812). The step failed.
you should first create the procedure before calling it, by below code:
CREATE PROC [dbo].[isp_ALTER_INDEX]
(
#dbName sysname,
#statsMode varchar(8) = 'SAMPLED',
#defragType varchar(10) = 'REORGANIZE',
#minFragPercent int = 25,
#maxFragPercent int = 100,
#minRowCount int = 0
)
AS
SET NOCOUNT ON
IF #statsMode NOT IN ('LIMITED', 'SAMPLED', 'DETAILED')
BEGIN
RAISERROR('#statsMode must be LIMITED, SAMPLED or DETAILED', 16, 1)
RETURN
END
IF #defragType NOT IN ('REORGANIZE', 'REBUILD')
BEGIN
RAISERROR('#defragType must be REORGANIZE or REBUILD', 16, 1)
RETURN
END
DECLARE
#i int, #objectId int, #objectName sysname, #indexId int, #indexName sysname,
#schemaName sysname, #partitionNumber int, #partitionCount int,
#sql nvarchar(4000), #edition int, #parmDef nvarchar(500), #allocUnitType nvarchar(60),
#indexType nvarchar(60), #online bit, #disabled bit, #dataType nvarchar(128),
#charMaxLen int
SELECT #edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
SELECT
IDENTITY(int, 1, 1) AS FragIndexId,
[object_id] AS ObjectId,
index_id AS IndexId,
avg_fragmentation_in_percent AS FragPercent,
record_count AS RecordCount,
partition_number AS PartitionNumber,
index_type_desc AS IndexType,
alloc_unit_type_desc AS AllocUnitType,
0 AS Online
INTO #FragIndex
FROM sys.dm_db_index_physical_stats (DB_ID(#dbName), NULL, NULL, NULL, #statsMode)
WHERE
avg_fragmentation_in_percent > #minFragPercent AND
avg_fragmentation_in_percent < #maxFragPercent AND
index_id > 0
ORDER BY ObjectId
-- LIMITED does not include data for record_count
IF #statsMode IN ('SAMPLED', 'DETAILED')
DELETE FROM #FragIndex
WHERE RecordCount < #minRowCount
-- Developer and Enterprise have the ONLINE = ON option for REBUILD
-- Indexes, including indexes on global temp tables, can be rebuilt online with the following exceptions:
-- Disabled indexes, XML indexes, Indexes on local temp tables, Partitioned indexes,
-- Clustered indexes if the underlying table contains LOB data types,
-- Nonclustered indexes that are defined with LOB data type columns
IF #defragType = 'REBUILD' AND #edition = 3
BEGIN
UPDATE #FragIndex
SET Online = 1
UPDATE #FragIndex
SET Online =
CASE
WHEN IndexType = 'XML INDEX' THEN 0
WHEN IndexType = 'NONCLUSTERED INDEX' AND AllocUnitType = 'LOB_DATA' THEN 0
ELSE 1
END
-- we can't determine if the indexes are disabled or partitioned yet,
-- so we'll need to figure that out during the loop
-- we also have to figure out if the table contains lob_data when
-- a clustered index exists during the loop
END
SELECT #i = MIN(FragIndexId)
FROM #FragIndex
SELECT
#objectId = ObjectId,
#indexId = IndexId,
#partitionNumber = PartitionNumber,
#indexType = IndexType,
#online = Online
FROM #FragIndex
WHERE FragIndexId = #i
WHILE ##ROWCOUNT <> 0
BEGIN
SET #sql = '
SELECT #objectName = o.[name], #schemaName = s.[name]
FROM ' + #dbName + '.sys.objects o
JOIN ' + #dbName + '.sys.schemas s
ON s.schema_id = o.schema_id
WHERE o.[object_id] = #objectId'
SET #parmDef = N'#objectId int, #objectName sysname OUTPUT, #schemaName sysname OUTPUT'
EXEC sp_executesql
#sql, #parmDef, #objectId = #objectId,
#objectName = #objectName OUTPUT, #schemaName = #schemaName OUTPUT
IF #indexType = 'CLUSTERED INDEX'
BEGIN
-- can't use online option if index is clustered and table contains following
-- data types: text, ntext, image, varchar(max), nvarchar(max), varbinary(max) or xml
-- CHARACTER_MAXIMUM_LENGTH column will equal -1 for max size or xml
SET #sql = '
SELECT #online = 0
FROM ' + #dbName + '.INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_NAME = #objectName AND
(DATA_TYPE IN (''text'', ''ntext'', ''image'') OR
CHARACTER_MAXIMUM_LENGTH = -1)'
SET #parmDef = N'#objectName sysname, #online bit OUTPUT'
EXEC sp_executesql
#sql, #parmDef, #objectName = #objectName, #online = #online OUTPUT
END
SET #sql = '
SELECT #indexName = [name], #disabled = is_disabled
FROM ' + #dbName + '.sys.indexes
WHERE [object_id] = #objectId AND index_id = #indexId'
SET #parmDef = N'
#objectId int, #indexId int, #indexName sysname OUTPUT, #disabled bit OUTPUT'
EXEC sp_executesql
#sql, #parmDef, #objectId = #objectId, #indexId = #indexId,
#indexName = #indexName OUTPUT, #disabled = #disabled OUTPUT
SET #sql = '
SELECT #partitionCount = COUNT(*)
FROM ' + #dbName + '.sys.partitions
WHERE [object_id] = #objectId AND index_id = #indexId'
SET #parmDef = N'#objectId int, #indexId int, #partitionCount int OUTPUT'
EXEC sp_executesql
#sql, #parmDef, #objectId = #objectId, #indexId = #indexId,
#partitionCount = #partitionCount OUTPUT
SET #sql = 'ALTER INDEX [' + #indexName + '] ON [' + #dbName + '].[' +
#schemaName + '].[' + #objectName + '] ' + #defragType
IF #online = 1 AND #disabled = 0 AND #partitionCount = 1
SET #sql = #sql + ' WITH (ONLINE = ON)'
IF #partitionCount > 1 AND #disabled = 0 AND #indexType <> 'XML INDEX'
SET #sql = #sql + ' PARTITION = ' + CAST(#partitionNumber AS varchar(10))
EXEC (#SQL)
SELECT #i = MIN(FragIndexId)
FROM #FragIndex
WHERE FragIndexId > #i
SELECT
#objectId = ObjectId,
#indexId = IndexId,
#partitionNumber = PartitionNumber,
#indexType = IndexType,
#online = Online
FROM #FragIndex
WHERE FragIndexId = #i
END
DROP TABLE #FragIndex
I want to find a specific data like Country name 'Spain' or any person name like 'John'
So is there any way to find which table's columns contain data Spain or John in a SQL Server database (remember these are not column Names, these are values stored in the columns)
Try below stored procedure, I found it here.
CREATE PROC SearchAllTables
(
#SearchStr nvarchar(100)
)
AS
BEGIN
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi
-- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128), #SearchStr2 nvarchar(110)
SET #TableName = ''
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
WHILE #TableName IS NOT NULL
BEGIN
SET #ColumnName = ''
SET #TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > #TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
SET #ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(#TableName, 2)
AND TABLE_NAME = PARSENAME(#TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > #ColumnName
)
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
Create this stored procedure and pass the data which you want to find
/****** Object: StoredProcedure [dbo].[FindMyData_String] Script Date: 07/04/2012 12:58:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[FindMyData_String]
#DataToFind NVARCHAR(4000),
#ExactMatch BIT = 0
AS
SET NOCOUNT ON
DECLARE #Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)
INSERT INTO #Temp(TableName,SchemaName, ColumnName, DataType)
SELECT C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type
FROM Information_Schema.Columns AS C
INNER Join Information_Schema.Tables AS T
ON C.Table_Name = T.Table_Name
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE Table_Type = 'Base Table'
And Data_Type In ('ntext','text','nvarchar','nchar','varchar','char')
DECLARE #i INT
DECLARE #MAX INT
DECLARE #TableName sysname
DECLARE #ColumnName sysname
DECLARE #SchemaName sysname
DECLARE #SQL NVARCHAR(4000)
DECLARE #PARAMETERS NVARCHAR(4000)
DECLARE #DataExists BIT
DECLARE #SQLTemplate NVARCHAR(4000)
SELECT #SQLTemplate = CASE WHEN #ExactMatch = 1
THEN 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
= ''' + #DataToFind + '''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
ELSE 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
Like ''%' + #DataToFind + '%''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
END,
#PARAMETERS = '#DataExists Bit OUTPUT',
#i = 1
SELECT #i = 1, #MAX = MAX(RowId)
FROM #Temp
WHILE #i <= #MAX
BEGIN
SELECT #SQL = REPLACE(REPLACE(#SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
FROM #Temp
WHERE RowId = #i
PRINT #SQL
EXEC SP_EXECUTESQL #SQL, #PARAMETERS, #DataExists = #DataExists OUTPUT
IF #DataExists =1
UPDATE #Temp SET DataFound = 1 WHERE RowId = #i
SET #i = #i + 1
END
SELECT SchemaName,TableName, ColumnName
FROM #Temp
WHERE DataFound = 1
I wouldn’t bother with any complex stored procedures as long as I can use some of the free tools that already exist on the market. Just install any of these and you’ll get the job done a lot faster.
SSMS toolpack – searches only data. Free for all versions except 2012
ApexSQL Search – searches objects and data
There is also SQL Search from Red Gate but I never used it myself.
We have a database setup that consists of two parts: a static structure, and dynamic additions. For each database, the dynamic can be different, and sometimes we don't have data for all the dynamic fields. Rigt now, we check for empties by looking at the total count of records in the entire table, but we want to move to a more refined method of checking for empties if possible. Is it possible to quickly check through several hundred fields and see which ones are empty and which ones are populated?
For searching for any rows that have NULLS in any column you can do this, first create this proc which is based on the code here Search all columns in all the tables in a database for a specific value
CREATE PROCEDURE FindMyData_StringNull
#DataToFind NVARCHAR(4000),
#ExactMatch BIT = 0
AS
SET NOCOUNT ON
DECLARE #Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)
INSERT INTO #Temp(TableName,SchemaName, ColumnName, DataType)
SELECT C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type
FROM Information_Schema.Columns AS C
INNER Join Information_Schema.Tables AS T
ON C.Table_Name = T.Table_Name
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE Table_Type = 'Base Table'
DECLARE #i INT
DECLARE #MAX INT
DECLARE #TableName sysname
DECLARE #ColumnName sysname
DECLARE #SchemaName sysname
DECLARE #SQL NVARCHAR(4000)
DECLARE #PARAMETERS NVARCHAR(4000)
DECLARE #DataExists BIT
DECLARE #SQLTemplate NVARCHAR(4000)
SELECT #SQLTemplate = 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
IS NULL
)
Set #DataExists = 1
Else
Set #DataExists = 0'
,
#PARAMETERS = '#DataExists Bit OUTPUT',
#i = 1
SELECT #i = 1, #MAX = MAX(RowId)
FROM #Temp
WHILE #i <= #MAX
BEGIN
SELECT #SQL = REPLACE(REPLACE(#SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
FROM #Temp
WHERE RowId = #i
PRINT #SQL
EXEC SP_EXECUTESQL #SQL, #PARAMETERS, #DataExists = #DataExists OUTPUT
IF #DataExists =1
UPDATE #Temp SET DataFound = 1 WHERE RowId = #i
SET #i = #i + 1
END
SELECT SchemaName,TableName, ColumnName
FROM #Temp
WHERE DataFound = 1
Call it like this
FindMyData_StringNull NULL,1
Assuming that you are just checking for whether or not there are any non-NULL values in the column, using EXISTS should generally be faster than getting a COUNT(*). The COUNT needs to scan the whole table to come up with the correct number. EXISTS just needs to find one row that satisfies the condition before it stops looking.
If the whole column is NULL then the time will be about the same, but in all of those cases where you have values it could be substantially shorter.
From Search all columns in all the tables in a database for a specific value
first create this function
CREATE PROCEDURE FindMyData_String
#DataToFind NVARCHAR(4000),
#ExactMatch BIT = 0
AS
SET NOCOUNT ON
DECLARE #Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)
INSERT INTO #Temp(TableName,SchemaName, ColumnName, DataType)
SELECT C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type
FROM Information_Schema.Columns AS C
INNER Join Information_Schema.Tables AS T
ON C.Table_Name = T.Table_Name
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE Table_Type = 'Base Table'
And Data_Type In ('ntext','text','nvarchar','nchar','varchar','char')
DECLARE #i INT
DECLARE #MAX INT
DECLARE #TableName sysname
DECLARE #ColumnName sysname
DECLARE #SchemaName sysname
DECLARE #SQL NVARCHAR(4000)
DECLARE #PARAMETERS NVARCHAR(4000)
DECLARE #DataExists BIT
DECLARE #SQLTemplate NVARCHAR(4000)
SELECT #SQLTemplate = CASE WHEN #ExactMatch = 1
THEN 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
= ''' + #DataToFind + '''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
ELSE 'If Exists(Select *
From ReplaceTableName
Where Convert(nVarChar(4000), [ReplaceColumnName])
Like ''%' + #DataToFind + '%''
)
Set #DataExists = 1
Else
Set #DataExists = 0'
END,
#PARAMETERS = '#DataExists Bit OUTPUT',
#i = 1
SELECT #i = 1, #MAX = MAX(RowId)
FROM #Temp
WHILE #i <= #MAX
BEGIN
SELECT #SQL = REPLACE(REPLACE(#SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
FROM #Temp
WHERE RowId = #i
PRINT #SQL
EXEC SP_EXECUTESQL #SQL, #PARAMETERS, #DataExists = #DataExists OUTPUT
IF #DataExists =1
UPDATE #Temp SET DataFound = 1 WHERE RowId = #i
SET #i = #i + 1
END
SELECT SchemaName,TableName, ColumnName
FROM #Temp
WHERE DataFound = 1
Now call it like this for rows with empty strings in any string type columns
exec FindMyData_String '',1
it will give you an output with column name, table name and schema name
Just keep in mind that it will search all tables
I would think the simplest solution is to use the CHECKSUM function. First you would want to determine the checksum on an empty row and then compare that to the other rows.
Select Checksum(*)
From Table
The catch with using * here is that it will include the PK. You would likely have to specify the individual columns excluding the PK to get an accurate read. So something like:
Select Checksum(Col1, Col2, Col3)
From Table
Checksum Function.
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