If you have 100 occurrences of "PRINT" in your stored procedure, is there a nice way to turn them all on/off when debugging an non-debugging?
I could add a variable #isdebug = 1
and later on, do something like
IF #isdebug = 1 PRINT #yourvar
and then just set the #isdebug to 0 or 1 depending on what you need.
Is there a nicer way to do this?
Nope, that is also what I have in procs
IF #debug = 1
BEGIN
print 'Something'
--or insert into a log table if you need the rows of a temp table
--or the results of a calculation
END
An expansion of this idea is to setup up a controlling string. This giving us more options rather than either on or off.
For example:
Stored procedure parameter declaration
(#Debug varchar(5), -- use bit wise control for debugging, currently 5 levels.
Simple substring to drive a testing/debug block.
if substring(#Debug, 1, 1) = '1'
For a test run you could enter '10001' for #Debug so that "level" 1 debugs show (ie initialisations) and only "level" 5 debugs show for the sub-section of code you are testing/debugging.
You could expand on this idea by using number values (ie 2-9) too. But that might be too over the top.
Related
I need to have the inputs entered into a parameter query in Excel WRITTEN to specific cells. Is this even possible?
To elaborate for better understanding, this is the SQL statement to pull data from the SQL server
{call dbo.SWMF_MXSalesJW (?,?)}
So when the connection is refreshed and the box to enter the parameters comes up, whatever date the user enters, I need that value written to Excel cell Z1.
Try to add one more parameter to your procedure
alter procedure sp_test
#dt_start date
,#dt_end date
,#need_params_back bit = 0 -- new param
as
begin
if #need_params_back = 0
begin
-- here is your code, for example:
select 1 as value
union all
select 2
end
else
begin
-- returning your params
select
#dt_start as dt_start
,#dt_end as dt_end
end
end
And call it twice in excel:
first time (let's name it Q1) with need_params_back = 1,
{call dbo.sp_test(?,?,1)}
you don't need here to map parameters to cells, let user input them.
second time (let's call it Q2) - as in your question.
{call dbo.sp_test(?,?,0)}
and map parameters to results of our first query (Q1).
But using such approach leads you to data refresh order, because you firstly need to update Q1 and only after you get results, update Q2 and all your other connections.
I hope, I've understood you correctly.
This is Sample code, the same in SQLFiddle
DECLARE #Test int
SET #Test = '6'
IF #Test > 5 PRINT N'Warning - large queries may take time'
ELSE PRINT N'Query will run normally';
GO
I have a query where the '#Test' variable can be changed to any number.
The above SQL kind of demonstrates the logic. If someone enters a number higher than 5 for example i want there to be a warning message advising the user about the larger query. Is this possible in SQL? I ran this code but it returns nothing. Am i in the right direction? thanks
I am trying to write a stored procedure that involves a lot of case when statements. I have a condition(when y=1, 10 more if conditions inside it), similarly for y=2 and y=3. I was trying to see if it could be simplified.
well, my application page has a drop down list with 3 options when i select either one of that, then i had a choice to select another 10 options in separate drop down list. So, i am trying to call my stored procedures in that page. thanks.
set #where = case
when #y = 1
then
case
when #value=1
then
//do something
else # value =2
then
//do something
... repeat then statement 8 more times
when #y=2
//10 time check conditions
when # y =3
//repeat again with #value condition 10 times
end
Using ssms 2012 to query a 2008R2 instance, I am trying to get a plan for a specific query using the DMVs like this:
SELECT t.text
, p.query_plan
from sys.dm_exec_query_stats qs
cross join sys.dm_exec_sql_text(qs.sql_handle) t
cross join sys.dm_exec_text_query_plan(qs.plan_handle,0,-1) p
where t.text like ...
The query plan column is getting cut off after 43,679 characters. Ending with
< /Outp
instead of
< /ShowPlanXML>
I tested this with a smaller query and the whole text was returned. The query in question is not that complex, but has a lot of columns, which may be making it a bit more verbose. Also, the value returned is not a link to the plan but just the XML in text form.
Is there a limit to what is stored in plan cache or I am doing something wrong in SSMS that it is not returning the value as a plan link in the column?
Even if the bug Aaron mentions in comments is in play here, you should be able to get around it with an SSMS tweak. You can directly cast the result of your query into the xml data type, and then return it that way.
If you're returning the XML in a grid view, go to Tools/Options/Query Results/SQL Server/Results to Grid and see what the setting for Maximum Characters Retrieved for XML data is, and bump it up to "Unlimited". This should allow you to circumvent the varchar limit.
Whoops! Wrong DMV. I needed to use dm_exec_query_plan not dm_exec_text_query_plan. That solved it - thanks for the replies.
Posting another answer as this may help someone else out in the future. There are a few approaches that I've found to work around the 43,679 character limitation in outputs displayed in Grid View as specific to this question. These approaches also work if your plan exceeds the SQL XML Data Type limit of 128 nested nodes.
The first, and arguably easiest option, is to fire up PowerShell ISE and follow the instructions outlined on this blog post by Patrick Keisler. Paste his script into the ISE editor, adjust the OFFSET values (recommended), output paths/names, and then run everything to generate the final sqlplan file.
If you don't want to use PowerShell, a kludgy TSQL method I cobbled together can also be used, as follows:
-- Quick and dirty script to output large execution plans from cache
-- Be sure to replace Plan Handle and Offset Values Below
DECLARE #query_plan_nvarmax NVARCHAR(MAX), #len_out INT, #sub_str INT = 0, #sub_end INT = 43679
DECLARE #full_query_plan TABLE
(
line INT IDENTITY(1,1),
qp_line NVARCHAR(MAX)
)
SELECT #query_plan_nvarmax = query_plan,
#len_out = LEN(query_plan)--, CAST(query_plan AS XML) as xml_query_plan
-- Usage: Get Query Offset Values From sys.dm_exec_query_stats DMV
-- sys.dm_exec_text_query_plan(plan_handle, OFFSET_START|DEFAULT, OFFSET_END|DEFAULT)
FROM sys.dm_exec_text_query_plan(0x050005005EDA4857307D56540300000001000000000000000000000000000000000000000000000000000000, 10078, 83616)
WHILE #sub_str < #len_out
BEGIN
INSERT INTO #full_query_plan (qp_line)
SELECT SUBSTRING(#query_plan_nvarmax, #sub_str, #sub_end)
SET #sub_str = #sub_end
SET #sub_end = #sub_end + 43679
IF #sub_end > #len_out
SET #sub_end = #len_out
END
-- Save Output of qp_line column to text editor and remove newline characters \r\n
-- I prefer Notepad++, but any editor will suffice then save output as a .sqlplan and open in SSMS
SELECT *
FROM #full_query_plan
Take note, you'll need to edit the output of the query in an external text editor to remove the newline characters \r\n and save the result as a .sqlplan file.
Is it possible, by using a stored procedure, to fetch an integer column value from resultset into a local variable, manipulate it there and then write it back to the resultset's column?
If so what would the syntax look like?
Something along the following lines should do the trick.
DECLARE #iSomeDataItem INT
SELECT #iSomeDataItem = TableColumName
FROM TableName
WHERE ID = ?
--Do some work on the variable
SET #iSomeDataItem = #iSomeDataItem + 21 * 2
UPDATE TableName
SET TableColumName = #iSomeDataItem
WHERE ID = ?
The downside to an implementation of this sort is that it only operates on a specific record however this may be what you are looking to achieve.
What you are looking for is probably more along the lines of a user-defined function that can be used in SQL just like any other built in function.
Not sure how this works in DB2, but for Oracle it would be something like this:
Create or replace Function Decrement (pIn Integer)
return Integer
Is
Begin
return pIn - 1;
end;
You could use this in a SQL, e.g.
Select Decrement (43)
From Dual;
should return the "ultimate answer" (42).
Hope this helps.
Thanks for the replies, i went another way and solved the problem without using a procedure. The core problem was to calculate a Date using various column values, the column values ahd to to converted to right format. Solved it by using large "case - when" statements in the select.
Thanks again... :-)
Why not just do the manipulation within the update statement? You don't need to load it into a variable, manipulate it, and then save it.
update TableName
SET TableColumnName=TableColumnName + 42 /* or what ever manipulation you want */
WHERE ID = ?
also,
#iSomeDataItem + 21 * 2
is the same as:
#iSomeDataItem + 42
The function idea is an unnecessary extra step, unless most of the following are true:
1) you will need to use this calculation in many places
2) the calculation is complex
3) the calculation can change