I want to pass an SQL command to a variable and execute aggregate function for that. but when I run it,
this error is shown, and nothing appear for #cnt value ,
Must declare the variable '#cnt'
What's my mistake ?
DECLARE #ret varchar(300);
set #ret = '';
declare #cnt int;
set #ret = 'select #cnt = count(*) from TBL1'
EXEC (#ret)
print #cnt
You could use sp_executesql to access a variable inside of your dynamic SQL String:
DECLARE #SQLString nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #cnt varchar(30);
SET #SQLString = N'SELECT #cntOUT = count(1) from tbl1';
SET #ParmDefinition = N'#cntOUT varchar(30) OUTPUT';
EXECUTE sp_executesql #SQLString, #ParmDefinition, #cntOUT=#cnt OUTPUT;
SELECT #cnt;
The exec statement signals the end of a batch, so the print statement doesn't know about #cnt.
Try this instead:
DECLARE #ret varchar(300)
set #ret = ''
set #ret = 'declare #cnt int
select #cnt = count(*) from [Load].RINData
print #cnt'
EXEC (#ret)
Related
Question 1)
We are planning to turn off XP CMDSHELL in SQL. Is there any alternative to the method I am using below:
Question 2)
Below SP
1.Creates new SQL Job every time
2.Runs the CMD command passed to it from SP param
3.Finally SP return result
USE [Test]
GO
/****** Object: StoredProcedure [dbo].[CMDSHELL_ALTERNATIVE] Script Date: 5/8/2020 5:44:39 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CMDSHELL_ALTERNATIVE]
#Command varchar(200),
#InvokedBySP varchar(100) = 'AdhocCalling'
AS
BEGIN
DECLARE #OutputFileName varchar(max)
DECLARE #OutputFilePath varchar(max)
DECLARE #JobOutcome int = 5
DECLARE #JobMessage varchar(max)
DECLARE #TodayDate DATE = GETDATE()
DECLARE #JobExecutionTime DATETIME
DECLARE #RandomeNumber BIGINT = CAST(RAND() * 1000000 AS BIGINT)
DECLARE #JobName varchar(100) = 'CMDSHELL_JOB_'+ CAST(#TodayDate AS VARCHAR)+'_'+CAST(#RandomeNumber AS VARCHAR)
SET #OutputFilePath ='C:\Users\OutputFiles\'
SET #OutputFileName = #JobName+'.txt'
DECLARE #FullOutputFilePathName varchar(max) = #OutputFilePath+#OutputFileName
DECLARE #jobId BINARY(16)
EXEC msdb.dbo.sp_add_job #job_name=#JobName,
#enabled=1,
#notify_level_eventlog=0,
#notify_level_email=2,
#notify_level_page=2,
#delete_level=0,
#category_name=N'[Uncategorized (Local)]',
#owner_login_name=N'sa', #job_id = #jobId OUTPUT
EXEC msdb.dbo.sp_add_jobserver #job_name=#JobName, #server_name = N'(local)'
EXEC msdb.dbo.sp_add_jobstep #job_name=#JobName, #step_name=N'step-1',
#step_id=1,
#cmdexec_success_code=0,
#on_success_action=1,
#on_fail_action=2,
#retry_attempts=0,
#retry_interval=0,
#os_run_priority=0, #subsystem=N'CmdExec',
#command=N'',
#database_name=N'master',
#output_file_name=N'',
#flags=0
EXEC msdb.dbo.sp_update_job #job_name=#JobName,
#enabled=1,
#start_step_id=1,
#notify_level_eventlog=0,
#notify_level_email=2,
#notify_level_page=2,
#delete_level=0,
#description=N'',
#category_name=N'[Uncategorized (Local)]',
#owner_login_name=N'sa',
#notify_email_operator_name=N'',
#notify_page_operator_name=N''
EXEC msdb.dbo.sp_update_jobstep
#job_name=#JobName,
#step_id=1 ,
#command=#Command,
#output_file_name=#FullOutputFilePathName
EXEC msdb.dbo.sp_start_job #JobName
SELECT distinct #JobOutcome = SJH.run_status
FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
WHERE SJH.job_id = SJ.job_id and SJ.Name = #JobName
WHILE (#JobOutcome != 3 AND #JobOutcome > 1)
BEGIN
print 'In a delay loop'
WAITFOR DELAY '00:00:02';
SELECT distinct #JobOutcome = SJH.run_status
FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
WHERE SJH.job_id = SJ.job_id and SJ.Name = #JobName
END
SET #JobExecutionTime = GETDATE()
SELECT #JobMessage = message FROM msdb..sysjobhistory SJH, msdb..sysjobs SJ
WHERE SJH.job_id = SJ.job_id and SJ.Name = #JobName
AND step_id = 1
IF #JobOutcome = 1
BEGIN
print 'Job successfull'
Declare #BulkInsertCommand varchar(max)
CREATE TABLE #temp (results NVARCHAR(755))
SET #BulkInsertCommand =
'BULK INSERT #temp
FROM ''' + #FullOutputFilePathName +'''
WITH
(
ROWTERMINATOR = ''\n'',
DataFileType=''widechar''
)'
EXEC (#BulkInsertCommand)
Select results from #temp
execute Test.dbo.CLR_CMDSHELL_LOGGING #JobName,#InvokedBySP,#Command,#JobExecutionTime,'Job Successfull',#JobMessage
END
ELSE
BEGIN
print 'Dynamic Job failed'
execute Test.dbo.CLR_CMDSHELL_LOGGING #JobName,#InvokedBySP,#Command,#JobExecutionTime,'Job Failed',#JobMessage
END
IF EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = #JobName)
EXEC msdb.dbo.sp_delete_job #job_name=#JobName
END
Now I run above SP using below code -
DECLARE #cmd VARCHAR(100)
SET #cmd = 'DIR /B C:\Users\Test'
--DECLARE #dirTable TABLE (oPut VARCHAR(max))
--insert #dirTable
EXEC [dbo].CMDSHELL_ALTERNATIVE #cmd
--select * from #dirTable
Result without Insert
enter image description here
Problem
Code above without insert works fine, returns result quickly. But when Insert statement is uncommented, SP runs forever.
enter image description hereenter code here
I can't figure out exactly where the blocking is. Any alternative/fix in above?
I have two stored procedures spParent and spParentChild. spParent calls spParentChild. Following the SPs:
CREATE PROCEDURE [dbo].[spParent]
#isApproved varchar(max) = 'TEST',
#ApplicationDBName varchar(100) = 'secDB',
#ApplicationInsertSPName varchar(100) = 'spParentChild',
#resultP varchar(max) output
AS
BEGIN
BEGIN TRY
SET NOCOUNT ON;
IF #resultP <> ''
BEGIN
RAISERROR('An error occurred in the parent SP.', 18, 0)
END
DECLare #resultCC varchar(max)
DECLARE #SP_Call Varchar(MAX)
SET #SP_Call = 'exec spParentChild ''1'', #resultCC output'
EXEC #SP_Call
select #resultCC
END TRY
BEGIN CATCH
Declare #ErrMessage Varchar(max)
Declare #ErrState Varchar(max)
Declare #ErrLine Varchar(max)
select #ErrMessage=ErrorMessage, #ErrLine=ErrorLine, #ErrState=ErrorState from fnGetError()
IF #ErrMessage is not Null
BEGIN
SELECT #resultP = #ErrMessage
SELECT #resultCC
END
ELSE
BEGIN
SELECT #resultP = 'An unknown error occurred.'
raiserror(#resultP,18,0)
END
END CATCH
END
CREATE PROCEDURE [dbo].[spParentChild]
#isApproved varchar(max) = 'TEST',
#resultC varchar(max) output
AS
BEGIN
BEGIN TRY
SET NOCOUNT ON;
RAISERROR('An error occurred in the child SP.', 18, 0)
END TRY
BEGIN CATCH
Declare #ErrMessage Varchar(max)
Declare #ErrState Varchar(max)
Declare #ErrLine Varchar(max)
select #ErrMessage=ErrorMessage, #ErrLine=ErrorLine, #ErrState=ErrorState from fnGetError()
IF #ErrMessage is not Null
BEGIN
SET #resultC = #ErrMessage
END
ELSE
BEGIN
SELECT #resultC = 'An unknown error occurred.'
END
END CATCH
END
As you can see spParent calls spParentChild. What I am needing is to use TSQL for the call, but it does not work. If I use the following all works fine, but I need TSQL:
EXEC spParentChild 1, #resultCC output
Can anyone help me in seeing what I am doing wrong or if this is even possible at all?
Thank you in advance.
Godfrey
To those who have a similar problem or need I am posting this solution I put together. It may sound as if this is crazy, but please believe when I tell you that I do require this and the actual SPs that need this are too long to post.
The spParentChild has not changed and remains as above. spParent is changed as shown below. The result is that spParent calls spParentChild. In his case if an error occurs in spParentChild the message is passed up to spParent in the output parameter.
I shall attempt to answer any questions should you have any. Following is spParent:
ALTER PROCEDURE [dbo].[spParent]
#isApproved varchar(max) = 'TEST',
#ApplicationDBName varchar(100) = 'SecDB',
#ApplicationInsertSPName varchar(100) = 'spParentChild',
#resultP varchar(max) output
AS
BEGIN
BEGIN TRY
SET NOCOUNT ON;
IF #resultP <> ''
BEGIN
RAISERROR('An error occurred in the parent SP.', 18, 0)
END
DECLARE #params NVarChar(max)
SET #params = '#resultCC VarChar(100) OUTPUT' -- OUTPUT Parameter for the called child SP
DECLARE #SP_Call NVarchar(MAX) -- sp_executesql requires NVarChar
SET #SP_Call = '[' + #ApplicationDBName + '].[dbo].[' + #ApplicationInsertSPName + '] ' + ' ''1'', #resultCC OUTPUT' -- ResultCC is the output parameter for the sp_executesql
EXEC sp_executesql #SP_Call, #params, #resultCC = #resultP OUTPUT -- Assign the value to the output parameter of this SP
-- EXEC spParentChild 1, #resultCC output -- THE ABOVE 5 LINES OF CODE ARE EQUAL TO THIS IS A HARDCODED CALL
if #resultP <> ''
BEGIN
SELECT #resultP [Returned Value]
END
END TRY
BEGIN CATCH
Declare #ErrMessage Varchar(max)
Declare #ErrState Varchar(max)
Declare #ErrLine Varchar(max)
select #ErrMessage=ErrorMessage, #ErrLine=ErrorLine, #ErrState=ErrorState from fnGetError()
IF #ErrMessage is not Null
BEGIN
SELECT #resultP = #ErrMessage
SELECT #ErrMessage
END
ELSE
BEGIN
SELECT #resultP = 'An unknown error occurred.'
SELECT 'bbb'
raiserror(#resultP,18,0)
END
END CATCH
END
I hope this assists someone in such need.
I have a certain address for a client and I need to get the latitude and longitude coordinates from Google using API Key, however either sp_OAGetProperty is returning blank instead of an XML data, what could be the reason for blank results it is returning?
This is for a geo analytics purposes, I have reconfigured the server to accept the execution of Ole Automation Procedures but still the same.
I'm using code.
use Development_Weekly
go
DECLARE #Response varchar(8000)
DECLARE #XML xml
DECLARE #Obj int
DECLARE #Result int
DECLARE #HTTPStatus int
DECLARE #Erreur varchar(MAX)
declare #MessageErreur varchar(max)
declare #MessageErreurAvecNumero varchar(max)
declare #URL varchar(600) =(select top 1 [BranchAddressURL] from [Development_Weekly].[dbo].[vwBranchLocation])
EXEC #Result = sp_OACreate 'MSXML2.ServerXMLHttp', #Obj OUT
if #Erreur <> 0 begin set #MessageErreur = 'sp_OACreate MSXML2.ServerXMLHttp.3.0 failed' end
--BEGIN TRY
EXEC #Result = sp_OAMethod #Obj, 'open', NULL, 'GET', #URL, false
if #Erreur <> 0 begin set #MessageErreur = 'sp_OAMethod MSXML2.ServerXMLHttp.3.0 failed' end
EXEC #Result = sp_OAMethod #Obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
if #Erreur <> 0 begin set #MessageErreur = 'sp_OAMethod MSXML2.ServerXMLHttp.3.0 failed' end
EXEC #Result = sp_OAMethod #Obj, send, NULL, ''
if #Erreur <> 0 begin set #MessageErreur = 'sp_OAMethod MSXML2.ServerXMLHttp.3.0 failed' end
EXEC #Result = sp_OAGetProperty #Obj, 'responseXML.xml', #Response OUT
if #Erreur <> 0 begin set #MessageErreur = 'sp_OAGetProperty MSXML2.ServerXMLHttp.3.0 failed' end
EXEC #Result = sp_OADestroy #Obj
if #Erreur <> 0 begin set #MessageErreur = 'sp_OADestroy MSXML2.ServerXMLHttp.3.0 failed' end
select #Result,#Response,#URL
I am not sure what exactly the reason is without a real url. But I always insert the response to a table variable instead of using #Response OUT to avoid truncated result. Here is what I usually do:
DECLARE #TABLEVAR TABLE (responseXml VARCHAR(MAX))
--skip some codes here
INSERT INTO #TABLEVAR
EXEC #Result = sp_OAGetProperty #Obj, 'responseXML.xml' --, #Response OUT
EXEC sp_OADestroy #Obj
SELECT #Response = responseXml FROM #TABLEVAR
This is NOT about using a table variable - this is about using a local variable to carry a db address within a dynamic SQL cursor which theoretically would work as follows:
-- Assume the global variables #sql, AnalysisLocation, and #sp_executeSql have been declared.
ALTER PROCEDURE [dbo].[sp_AggregateCompliance_Report]
#clientID int,
#InvScrDBLocation nvarchar(250),
#JoinFilter nvarchar(max) = '',
#Criteria nvarchar(max) = '',
#Year int = NULL
as
declare #sql nvarchar(4000)
set #sql = '
IF EXISTS (SELECT * FROM sys.tables WHERE name = ''tmp_Aggregate_Compliance_counts'')
TRUNCATE TABLE tmp_Aggregate_Compliance_counts
ELSE
CREATE TABLE tmp_Aggregate_Compliance_counts (
pfc_fk_prv_pkid int,
RxYear int,
RxMonth int,
Compliance decimal (6,5))
' print #sql EXEC sp_executesql #sql
SET #Criteria = isnull(case when #Criteria like 'WHERE %' then 'AND '+substring(#criteria,7,len(#criteria)-6) else #Criteria end ,'')
SET #Year = isnull(#year, year(getdate())-1)
set #sql = '
DECLARE #fk_cli_pkid INT
, #ServerAndDB_for_pfcAppended nvarchar(100)
DECLARE client_set CURSOR FOR
SELECT DISTINCT mtx.fk_cli_pkid, SettingValue+ ''.dbo.pfc_appended''
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx
JOIN prola7.Invoice_Screens.dbo.client_definition AS def
ON mtx.fk_cli_pkID = def.fk_cli_pkid
AND fk_lkSettings_pkID = 45
AND RecordStatus = 1
OPEN client_set
FETCH next FROM client_set
INTO #fk_cli_pkid, #ServerAndDB_for_pfcAppended
WHILE ##FETCH_STATUS = 0 BEGIN
INSERT INTO tmp_Aggregate_Compliance_counts (pfc_fk_prv_pkid, RxYear, RxMonth, Compliance)
SELECT pfc.pfc_fk_prv_pkid
, year(mtx.pfc_dateofservice) AS RxYear
, 0 AS RxMonth
, cast(mtx.Compliance as decimal (6,5))
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx
LEFT OUTER JOIN #ServerAndDB_for_pfcAppended AS pfc
ON mtx.pp_clientfile = pfc.pp_clientfile
AND mtx.pp_mirror_pkid = pfc.pp_mirror_pkid
AND mtx.fk_cli_pkid = #fk_cli_pkid
'+#JoinFilter+'
WHERE pfc.pfc_status = 0
AND year(mtx.pfc_dateofservice) = '+cast(#Year as nvarchar)+'
'+#Criteria+'
GROUP BY pfc.pfc_fk_prv_pkid, year(mtx.pfc_dateofservice)
FETCH next FROM client_set
INTO #fk_cli_pkid, #ServerAndDB_for_pfcAppended
END
CLOSE client_set
DEALLOCATE client_set
' print #sql EXEC sp_executesql #sql
This creates no syntax errors when compiling the dynamic code, however when calling this procedure: Msg 1087, Level 15, State 2, Line 27
Must declare the table variable "#ServerAndDB_for_pfcAppended".
When I use this type of structure passing the location variable in as a global variable from outside the procedure it accepts it correctly, however as a local variable it seems to default to presuming I intend it to be a table variable.
I do NOT want to create a table variable. Is this an impossible structure?
The error is caused by the fact that you are attempting to have a parametrised table name. This is not possible, and whenever a table name should be a parameter, a dynamic query is used, basically like this:
SET #sql = 'SELECT … FROM ' + #tablename + ' WHERE …'
I think, in your situation the cursor should be taken out of the dynamic query, except for the part that uses the parametrised table name. Something like this should probably do:
ALTER PROCEDURE [dbo].[sp_AggregateCompliance_Report]
#clientID int,
#InvScrDBLocation nvarchar(250),
#JoinFilter nvarchar(max) = '',
#Criteria nvarchar(max) = '',
#Year int = NULL
as
declare #sql nvarchar(4000)
set #sql = '
IF EXISTS (SELECT * FROM sys.tables WHERE name = ''tmp_Aggregate_Compliance_counts'')
TRUNCATE TABLE tmp_Aggregate_Compliance_counts
ELSE
CREATE TABLE tmp_Aggregate_Compliance_counts (
pfc_fk_prv_pkid int,
RxYear int,
RxMonth int,
Compliance decimal (6,5))
' print #sql EXEC sp_executesql #sql
SET #Criteria = isnull(case when #Criteria like 'WHERE %' then 'AND '+substring(#criteria,7,len(#criteria)-6) else #Criteria end ,'')
SET #Year = isnull(#year, year(getdate())-1)
DECLARE #fk_cli_pkid INT
, #ServerAndDB_for_pfcAppended nvarchar(100)
DECLARE client_set CURSOR FOR
SELECT DISTINCT mtx.fk_cli_pkid, SettingValue+ ''.dbo.pfc_appended''
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx
JOIN prola7.Invoice_Screens.dbo.client_definition AS def
ON mtx.fk_cli_pkID = def.fk_cli_pkid
AND fk_lkSettings_pkID = 45
AND RecordStatus = 1
OPEN client_set
FETCH next FROM client_set
INTO #fk_cli_pkid, #ServerAndDB_for_pfcAppended
WHILE ##FETCH_STATUS = 0 BEGIN
set #sql = '
INSERT INTO tmp_Aggregate_Compliance_counts (pfc_fk_prv_pkid, RxYear, RxMonth, Compliance)
SELECT pfc.pfc_fk_prv_pkid
, year(mtx.pfc_dateofservice) AS RxYear
, 0 AS RxMonth
, cast(mtx.Compliance as decimal (6,5))
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx
LEFT OUTER JOIN #ServerAndDB_for_pfcAppended AS pfc
ON mtx.pp_clientfile = pfc.pp_clientfile
AND mtx.pp_mirror_pkid = pfc.pp_mirror_pkid
AND mtx.fk_cli_pkid = #fk_cli_pkid
'+#JoinFilter+'
WHERE pfc.pfc_status = 0
AND year(mtx.pfc_dateofservice) = '+cast(#Year as nvarchar)+'
'+#Criteria+'
GROUP BY pfc.pfc_fk_prv_pkid, year(mtx.pfc_dateofservice)
' print #sql EXEC sp_executesql #sql
FETCH next FROM client_set
INTO #fk_cli_pkid, #ServerAndDB_for_pfcAppended
END
CLOSE client_set
DEALLOCATE client_set
I have a piece of dynamic SQL I need to execute, I then need to store the result into a variable.
I know I can use sp_executesql but can't find clear examples around about how to do this.
If you have OUTPUT parameters you can do
DECLARE #retval int
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #tablename nvarchar(50)
SELECT #tablename = N'products'
SELECT #sSQL = N'SELECT #retvalOUT = MAX(ID) FROM ' + #tablename;
SET #ParmDefinition = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
But if you don't, and can not modify the SP:
-- Assuming that your SP return 1 value
create table #temptable (ID int null)
insert into #temptable exec mysp 'Value1', 'Value2'
select * from #temptable
Not pretty, but works.
DECLARE #vi INT
DECLARE #vQuery NVARCHAR(1000)
SET #vQuery = N'SELECT #vi= COUNT(*) FROM <TableName>'
EXEC SP_EXECUTESQL
#Query = #vQuery
, #Params = N'#vi INT OUTPUT'
, #vi = #vi OUTPUT
SELECT #vi
DECLARE #tab AS TABLE (col1 VARCHAR(10), col2 varchar(10))
INSERT into #tab EXECUTE sp_executesql N'
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2
UNION ALL
SELECT 1 AS col1, 2 AS col2'
SELECT * FROM #tab
Return values are generally not used to "return" a result but to return success (0) or an error number (1-65K). The above all seem to indicate that sp_executesql does not return a value, which is not correct. sp_executesql will return 0 for success and any other number for failure.
In the below, #i will return 2727
DECLARE #s NVARCHAR(500)
DECLARE #i INT;
SET #s = 'USE [Blah]; UPDATE STATISTICS [dbo].[TableName] [NonExistantStatisticsName];';
EXEC #i = sys.sp_executesql #s
SELECT #i AS 'Blah'
SSMS will show this
Msg 2727, Level 11, State 1, Line 1
Cannot find index 'NonExistantStaticsName'.
If you want to return more than 1 value use this:
DECLARE #sqlstatement2 NVARCHAR(MAX);
DECLARE #retText NVARCHAR(MAX);
DECLARE #ParmDefinition NVARCHAR(MAX);
DECLARE #retIndex INT = 0;
SELECT #sqlstatement = 'SELECT #retIndexOUT=column1 #retTextOUT=column2 FROM XXX WHERE bla bla';
SET #ParmDefinition = N'#retIndexOUT INT OUTPUT, #retTextOUT NVARCHAR(MAX) OUTPUT';
exec sp_executesql #sqlstatement, #ParmDefinition, #retIndexOUT=#retIndex OUTPUT, #retTextOUT=#retText OUTPUT;
returned values are in #retIndex and #retText
Declare #variable int
Exec #variable = proc_name
DECLARE #ValueTable TABLE
(
Value VARCHAR (100)
)
SELECT #sql = N'SELECT SRS_SizeSetDetails.'+#COLUMN_NAME+' FROM SRS_SizeSetDetails WHERE FSizeID = '''+#FSizeID+''' AND SRS_SizeSetID = '''+#SRS_SizeSetID+'''';
INSERT INTO #ValueTable
EXEC sp_executesql #sql;
SET #Value='';
SET #Value = (SELECT TOP 1 Value FROM #ValueTable)
DELETE FROM #ValueTable
This worked for me:
DECLARE #SQL NVARCHAR(4000)
DECLARE #tbl Table (
Id int,
Account varchar(50),
Amount int
)
-- Lots of code to Create my dynamic sql statement
insert into #tbl EXEC sp_executesql #SQL
select * from #tbl
Here's something you can try
DECLARE #SqlStatement NVARCHAR(MAX) = ''
,#result XML
,#DatabaseName VARCHAR(100)
,#SchemaName VARCHAR(10)
,#ObjectName VARCHAR(200);
SELECT #DatabaseName = 'some database'
,#SchemaName = 'some schema'
,#ObjectName = 'some object (Table/View)'
SET #SqlStatement = '
SELECT #result = CONVERT(XML,
STUFF( ( SELECT *
FROM
(
SELECT TOP(100)
*
FROM ' + QUOTENAME(#DatabaseName) +'.'+ QUOTENAME(#SchemaName) +'.' + QUOTENAME(#ObjectName) + '
) AS A1
FOR XML PATH(''row''), ELEMENTS, ROOT(''recordset'')
), 1, 0, '''')
)
';
EXEC sp_executesql #SqlStatement,N'#result XML OUTPUT', #result = #result OUTPUT;
SELECT DISTINCT
QUOTENAME(r.value('fn:local-name(.)', 'VARCHAR(200)')) AS ColumnName
FROM #result.nodes('//recordset/*/*') AS records(r)
ORDER BY ColumnName
This was a long time ago, so not sure if this is still needed, but you could use ##ROWCOUNT variable to see how many rows were affected with the previous sql statement.
This is helpful when for example you construct a dynamic Update statement and run it with exec. ##ROWCOUNT would show how many rows were updated.
Here is the definition