Is there any kind of environment variable (or something) that will tell me if a script is running inside SSMS? For example at the top of my query in SSMS I have this:
declare #StartDate datetime, #EndDate datetime, #ThisYear datetime, #IncludeZeroBalance int;
set #StartDate = '20080101';
set #EndDate = '20170201';
set #ThisYear = year(GetDate());
set #IncludeZeroBalance = 0;
I'd like to be able to leave that in the query but "wrap" it with something so it's only seen/run when in SSMS. Some kind of pragma like #IF SSMS or similar.
I'm thinking there's not something like this (searching has proven fruitless) but am hoping someone knows a trick to do that kind of thing...
You can use the APP_NAME() function to get the name of the application that the calling application specified in its connectionstring. Example:
declare #MyAppname nvarchar(50);
select #MyAppname = app_name();
if (#MyAppname = 'Microsoft SQL Server Management Studio - Query')
begin
print 'Do SSMS stuff here'
end
else
begin
print 'Do non-SSMS stuff here'
end;
Related
I'm having a problem and I don't know how to solve it, I have searched the web and found good advice but I can't work it out.
This is the problem: I have a SQL Server instance running on my PC, and I linked one of the main servers SRVOLD\SQLDESA to it. I want to execute main server's stored procedures from my PC's SQL Server instance and insert the results into a new table. I found the perfect way to do it using the following:
SELECT *
INTO Bank
FROM OPENQUERY([SRVOLD\SQLDESA],
'EXEC Bank_Database.Bank.usp_GetTDcodes 1, 5')
GO
There is important information about this server, it's SQL Server version is 2008. Keep this in mind for later.
Ok so I managed to executed this Stored Procedure but I found out something, turns out that inside this Stored Procedure there's an execution of another stored procedure, check this out:
1st stored procedure:
CREATE PROCEDURE Bank.usp_GetTDcodes
(#code TINYINT = NULL, #qty TINYINT = NULL)
WITH ENCRYPTION
AS
DECLARE ##msg VARCHAR(100)
DECLARE ##OK INT
DECLARE ##today CHAR(30)
SELECT ##today = CONVERT(VARCHAR(30), GETDATE(), 112) + ' ' +
CONVERT(VARCHAR(30), GETDATE(), 8)
SELECT bnk_code, bnk_descr
FROM CODBNK
WHERE bnk_code < 50
EXECUTE ##OK = Bank.usp_WriteEvent #qty, #code, ##today, 500
IF ##OK <> 0
RETURN ##OK
RETURN 0
GO
Now let's look inside the 2nd stored procedure:
CREATE PROCEDURE Bank.usp_WriteEvent
(#code TINYINT = NULL,
#qty TINYINT = NULL,
#date DATETIME = NULL,
#number SMALLINT = NULL,
#ideve INT = 0 OUTPUT)
WITH ENCRYPTION
AS
DECLARE ##sdate VARCHAR(30)
DECLARE ##ret SMALLINT
INSERT INTO Event (eve_code, eve_qty, eve_date, eve_number)
VALUES (#code, #qty, #date, #number)
SET ##ret = ##error
IF ##ret = 0
BEGIN
SELECT #ideve = ##IDENTITY
SELECT ##sdate = CONVERT(VARCHAR(30), #date, 112) + ' ' +
VARCHAR(30), #date, 8)
END
ELSE
RETURN ##ret
GO
When I executed the 1st stored procedure, I was able to insert it's result into a new table, but I was hoping to find a new row inserted in the table Event, because that is the expected result when executing 2nd stored procedure.
So I started to search online and managed to achieve this by doing the following:
SELECT *
INTO Bank
FROM OPENQUERY([SRVTEST\SQLDESA],
'SET FMTONLY OFF;SET NOCOUNT ON;EXEC Bank_Database.Bank.usp_GetTDcodes 1, 5')
GO
So, the SET FMTONLY OFF;SET NOCOUNT ON worked and I was happy. But something happened...
I needed to execute the same stored procedure, but this time adding a new linked server SRVNEW\SQLDESA. This server's version is 2012, so the new solution didn't work. I kept trying and trying different ways, there's just one way to make it work and is the following:
EXEC [SRVNEW\SQLDESA].[Bank_Database].Bank.usp_GetTDcodes 1,5
But it doesn't work for me because I need the 1st stored procedure result into a new table. And I don't know its schema that's why SELECT INTO works best for me.
I don't know what else I can do, maybe is the OPENQUERY that doesn't work? Do I need to change something else?
PD: I also tried using OPENROWSET didn't work either.
Thanks in advance, and have a nice day!
Peace!
Some references: http://www.sommarskog.se/share_data.html#OPENQUERY
There is a SQL script with some declared variables. I want to run this script for various sets of values of these variables and see the outputs. How do I do this?
Just a note: this answer is copied from here but is a great resource for what you are asking.
More examples for set-based vs. procedural can be found here, here and here.
And here is an actual example in SQL code:
DECLARE #someFlag INT
SET #someFlag = 0
WHILE (#someFlag <=5)
BEGIN
PRINT #someFlag
SET #someFlag = #someFlag + 1
END
GO
If you have the appropriate permissions to do it, you could set up the script as a stored procedure and then run the procedure multiple times. Reference on how to do it: http://msdn.microsoft.com/en-us/library/ms187926(v=sql.100).aspx
You don't have to make a permanent proc either, if you don't need it or want it in whatever database you're running it in, you can set it up as a temp proc instead.
So instead of CREATE PROCEDURE dbo.usp_SomeProcedure AS ....
you would do CREATE PROCEDURE #usp_SomeProcedure
Your other option is to put your script into an nvarchar(max) variable and use that along with your other variables to run sp_executesql (http://msdn.microsoft.com/en-us/library/ms188001.aspx).
I would either use a Cursor or a While loop (preference would be the While). It would be something like this
DECLARE #i INT
SET #i = 1
WHILE (#i <=10)
BEGIN
-- do whatever you need to do
SET #i = #i + 1
END
Assume I have a normal SQL procedure which has a few arguments.
During debugging it would be nice if i could assign some values to these arguments so that I can just highlight the body of the proc and execute it (as opposed to manually replace the variable with values.
Is there any way to do this? I tried:
#Date1 datetime,
#Date2 datetime
SET #Date1 = '2012-03-23'
but it doesn't like it??
Try
DECLARE #Date1 datetime
SET #Date1 = '2012-03-23'
Looks like you were missing the declare statement. If it doesn't like the '2012-03-23' part, you may have to cast it.
If you're going to do this, I suggest you consider adding a #Debug parameter to your procedures:
create procedure dbo.SomeProc #p1 int, #p2 int, #Debug bit = 0x0
as
set nocount on
begin
if #Debug = 0x1 -- set test values only if debugging
begin
print 'Start debugging'
set #p1 = 1
set #p2 = 2
end
/* your code continues here... */
end
Then when you want to test your code, just execute the procedure with #Debug = 0x1 to execute the debugging code.
Put 'declare' word in front of #Date1
I'm not talking about doing a "SET NOCOUNT OFF". But I have a stored procedure which I use to insert some data into some tables. This procedure creates a xml response string, well let me give you an example:
CREATE PROCEDURE [dbo].[insertSomeData] (#myParam int) AS
DECLARE #reply varchar(2048)
... Do a bunch of inserts/updates...
SET #reply = '<xml><big /><outputs /></xml>'
SELECT #reply
GO
So I put together a script which uses this SP a bunch of times, and the xml "output" is getting to be too much (it's crashed my box once already).
Is there a way to suppress or redirect the output generated from this stored procedure? I don't think that modifying this stored procedure is an option.
thanks.
I guess i should clarify. This SP above is being called by a T-SQL Update script that i wrote, to be run through enterprise studio manager, etc.
And it's not the most elegant SQL i've ever written either (some psuedo-sql):
WHILE unprocessedRecordsLeft
BEGIN
SELECT top 1 record from updateTable where Processed = 0
EXEC insertSomeData #param = record_From_UpdateTable
END
So lets say the UpdateTable has some 50k records in it. That SP gets called 50k times, writing 50k xml strings to the output window. It didn't bring the sql server to a stop, just my client app (sql server management studio).
The answer you're looking for is found in a similar SO question by Josh Burke:
-- Assume this table matches the output of your procedure
DECLARE #tmpNewValue TABLE ([Id] int, [Name] varchar(50))
INSERT INTO #tmpNewValue
EXEC [ProcedureB]
-- SELECT [Id], [Name] FROM #tmpNewValue
I think I found a solution.
So what i can do now in my SQL script is something like this (sql-psuedo code):
create table #tmp(xmlReply varchar(2048))
while not_done
begin
select top 1 record from updateTable where processed = 0
insert into #tmp exec insertSomeData #param=record
end
drop table #tmp
Now if there was a even more efficient way to do this. Does SQL Server have something similar to /dev/null? A null table or something?
Answering the question, "How do I suppress stored procedure output?" really depends on what you are trying to accomplish. So I want to contribute what I encountered:
I needed to supress the stored procedure (USP) output because I just wanted the row count (##ROWCOUNT) from the output. What I did, and this may not work for everyone, is since my query was already going to be dynamic sql I added a parameter called #silentExecution to the USP in question. This is a bit parameter which I defaulted to zero (0).
Next if #silentExecution was set to one (1) I would insert the table contents into a temporary table, which is what would supress the output and then execute ##ROWCOUNT with no problem.
USP Example:
CREATE PROCEDURE usp_SilentExecutionProc
#silentExecution bit = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE #strSQL VARCHAR(MAX);
SET #strSQL = '';
SET #strSQL = 'SELECT TOP 10 * ';
IF #silentExecution = 1
SET #strSQL = #strSQL + 'INTO #tmpDevNull ';
SET #strSQL = #strSQL +
'FROM dbo.SomeTable ';
EXEC(#strSQL);
END
GO
Then you can execute the whole thing like so:
EXEC dbo.usp_SilentExecutionProc #silentExecution = 1;
SELECT ##ROWCOUNT;
The purpose behind doing it like this is if you need the USP to be able to return a result set in other uses or cases, but still utilize it for just the rows.
Just wanted to share my solution.
I have recently come across with a similar issue while writing a migration script and since the issue was resolved in a different way, I want to record it.
I have nearly killed my SSMS Client by running a simple while loop for 3000 times and calling a procedure.
DECLARE #counter INT
SET #counter = 10
WHILE #counter > 0
BEGIN
-- call a procedure which returns some resultset
SELECT #counter-- (simulating the effect of stored proc returning some resultset)
SET #counter = #counter - 1
END
The script result was executed using SSMS and default option on query window is set to show “Results to Grid”[Ctrl+d shortcut].
Easy Solution:
Try setting the results to file to avoid the grid to be built and painted on the SSMS client. [CTRL+SHIFT+F keyboard shortcut to set the query results to file].
This issue is related to : stackoverflow query
Man, this is seriously a case of a computer doing what you told it to do instead of what you wanted it to do.
If you don't want it to return results, then don't ask it to return results. Refactor that stored procedure into two:
CREATE PROCEDURE [dbo].[insertSomeData] (#myParam int) AS
BEGIN
DECLARE #reply varchar(2048)
--... Do a bunch of inserts/updates...
EXEC SelectOutput
END
GO
CREATE PROCEDURE SelectOutput AS
BEGIN
SET #reply = '<xml><big /><outputs /></xml>'
SELECT #reply
END
From which client are you calling the stored procedure? Say it was from C#, and you're calling it like:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
var read = com.ExecuteReader();
This will not yet retrieve the result from the server; you have to call Read() for that:
read.Read();
var myBigString = read[0].ToString();
So if you don't call Read, the XML won't leave the Sql Server. You can even call the procedure with ExecuteNonQuery:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
com.ExecuteNonQuery();
Here the client won't even ask for the result of the select.
You could create a SQL CLR stored procedure that execs this. Should be pretty easy.
I don't know if SQL Server has an option to suppress output (I don't think it does), but the SQL Query Analyzer has an option (under results tab) to "Discard Results".
Are you running this through isql?
You said your server is crashing. What is crashing the application that consumes the output of this SQL or SQL Server itself (assuming SQL Server).
If you are using .Net Framework application to call the stored procedure then take a look at SQLCommand.ExecuteNonQuery. This just executes stored procedure with no results returned. If problem is at SQL Server level then you are going to have to do something different (i.e. change the stored procedure).
You can include in the SP a parameter to indicate if you want it to do the select or not, but of course, you need to have access and reprogram the SP.
CREATE PROCEDURE [dbo].[insertSomeData] (#myParam int, #doSelect bit=1) AS
DECLARE #reply varchar(2048)
... Do a bunch of inserts/updates...
SET #reply = '<xml><big /><outputs /></xml>'
if #doSelect = 1
SELECT #reply
GO
ever tried SET NOCOUNT ON; as an option?
Is it possible to determine the type of a local variable at runtime in TSQL?
For example, say I wanted to do something along these lines:
IF ( #value IS INTEGER )
Or
IF ( TYPEOF(#value) = <whatever> )
Does anyone know of any way to accomplish this?
EDIT: This is not for a specific task, this is more of a general knowledge question. I do appreciate answers that indicate that the type should be known since it is declared within the same batch, I am curious as to whether the type can be determined at runtime.
run this
declare #d int
select #d = 500
if cast(sql_variant_property(#d,'BaseType') as varchar(20)) = 'int'
print 'yes'
else
print 'no'
using SQL 2019 , below code still working
DECLARE #MyVar int;SET #MyVar = 99;
DECLARE #MyVarDataType varchar(50);
SET #MyVarDataType = cast(SQL_VARIANT_PROPERTY(#MyVar,'BaseType') AS varchar);
PRINT #MyVarDataType
I don't think so - BUT it is a local variable so are declaring it in the same procedure so you would know the type anyways - or am I missing something?