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
Related
I have a application runs this T-SQL command:
exec sp_executesql #statement = N'mysp #timestamp=0',
#params = N'#0 datetime',
#0 = '2021-04-08 20:59:10.987'
I log the timestamp value and I get empty for some reason:
1900-01-01 00:00:00.000
This is the stored procedure code:
ALTER PROCEDURE [dbo].[mysp]
#TimeStamp DATETIME = NULL
AS
SET NOCOUNT ON
DECLARE
....
BEGIN TRY
SELECT #TimeStamp
...
What is wrong in the T-SQL command? How should it be in this structure?
What I see is procedure named mysp which expects one parameter named #timestamp. The =0 part sets the value of this parameter to 0. It is not the name of another paramter. When interpreted as a datetime, a 0 value matches the 1900-01-01 you observed.
I expect this is what the application is trying to do:
exec sp_executesql #statement = N'mysp #timestamp',
#params = N'#timestamp datetime',
#timestamp = '2021-04-08 20:59:10.987'
Alternatively:
exec sp_executesql #statement = N'mysp #timestamp=#0',
#params = N'#0 datetime',
#0 = '2021-04-08 20:59:10.987'
In communicating with developers about how to fix this on their end, keep in mind they are probably not writing the exec sp_executesql code directly. Rather, they are more likely using a tool to just call mysp that alters the code to use sp_executesql behind the scenes for them. This is common practice as a safe way for developers to use parameterized queries in their code and avoid Sql Injection security issues.
I have a stored SQL procedure I would like to generalize. This involves passing the Table name, a start time, and an end time through as variables, so one doesn't have to edit the procedure every time. I'm trying to use basic python variables to prompt the user. (Start = int(input("Enter Start Time: "))
I just haven't found a simple way to do this. I've used 'execute sp_execute_external_scripts' and have been seeing if Pyodbc is the right tool for this, but nothing so far has worked, and I didn't fully understand the MS documentation/tutorial for creating a wrapper. So what is the easiest way to prompt the user for input that can be injected into a procedure as a variable? I feel like I'm missing something very simple here.
Upon reading comments here, my original method is overbroad and would require dynamicsql, which I'm not automatically opposed to, but it seems safer to create procedures for individual tables. So I should only need to push Start, End and ChunkSize as integer variables into the procedure.
SOLVED: I got the desired results by writing a small python program using pyodbc. Thank you for the help and gentle nudging away from my original, naive idea.
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=CROWN;'
'Database=ControlInformation;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
Start = int(input("Enter Start Time: "))
End = int(input("Enter End Time: "))
ChunkSize = int(input("Enter # of files to delete at once: "))
cursor.execute('exec PurgeCurrencyExchangeRates #start = %d, #end = %d,
#ChunkSize = %d' %(Start, End, ChunkSize))
cursor.commit(),
connection.close()
SQL stored procedure
CREATE PROCEDURE UserInput
#r int = 1,
#Start bigint = 0,
#End bigint = 0,
#TableName varchar(40) = 'CurrencyExchangeRates',
#ChunkSize int = 10000,
#ColumnName varchar(40) = 'Timestamp'
AS
BEGIN
SET NOCOUNT ON;
while #r > 0
delete top(#ChunkSize)
ControlInformation.dbo.#TableName
where #ColumnName > #Start and #ColumnName < #End
set #r = ##ROWCOUNT
The stored procedure should be something like:
use CurrencyExchangeRates
go
CREATE PROCEDURE PurgeCurrencyExchangeRates
#Start bigint = 0,
#End bigint = 0,
#ChunkSize int = 10000
AS
BEGIN
SET NOCOUNT ON;
declare #r int = 1;
while #r > 0
begin
delete top(#ChunkSize)
from dbo.CurrencyExchangeRates
where [Timestamp] >= #Start and [Timestamp] < #End
set #r = ##ROWCOUNT
end
end
Maybe you need in python:
Start = int(input("Enter Start Time: "))
sql = 'exec UserInput #start =?'
cursor.execute(sql, Start)
cursor.commit()
If you really want to make the table name dynamic then you'll need to use dynamic SQL, like so:
ALTER PROCEDURE DeleteFrom
#tableName sysname ='Table0'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(4000);
SET #sql = N'DELETE TOP (1) FROM ' + QUOTENAME(#tableName);
EXEC(#sql);
END
In a stored procedure, is setting something a parameter and declaring something different?
For example: if I needed to make something a parameter which would be right or wrong?
Alter Prodedure dbo.users_checkin
#userid INT
AS
Begin
OR
Alter Proc
Begin
Declare #userid INT
Declare #date1 DATE
Thank you!
I have this stored procedure:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but when I tried to execute it,it has this error
The formal parameter “#mode” was not declared as an OUTPUT parameter, but the actual parameter passed in requested output.
I tried to set #mode as output like this:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but the it returns a null value.
Any fix for this? Thanks in advance.
the sequence of parameter in store procedure is that first use input parameter then use output parameter:-
you can see this link for more knowledge of store procedure:-
http://www.codeproject.com/Articles/126898/Sql-Server-How-To-Write-a-Stored-Procedure-in-SQL
ALTER PROCEDURE spCertificationType
#mode int,
#result nvarchar(15) output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
I fixed this error a different way.
I had removed the OUTPUT statement after a parameter in my SP.
I then got the error.
I then went back to the SQLDataSource Configure Data Source wizard and went through the steps again. I discovered that changing the SP made the wizard delete the settings associated with the parameter that used to have OUTPUT after it.
In my case, I had declared the OUTPUT parameter last but was also getting a similar exception.
I moved the default parameters (like #var FLOAT = null) to the end after the output parameter then it started working.
I'm fairly new to SQL and was trying to write a procedure that would check a passed in value and set a local datetime variable and then return that variable.
USE [MyDB]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [Common].[Update_Date]
#Status_ID int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Date_Value DATETIME
IF #Status_ID = 2
SET #Date_Value = GETDATE()
ELSE
SET #Date_Value = NULL
RETURN #Date_Value
END
GO
When I try to execute this script I get the following error:
Msg 257, Level 16, State 3, Procedure Update_Date, Line 19
Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
Is it trying to do something with my #Status_ID parameter?
Stored procedures return values by using OUTPUT parameters:
CREATE PROCEDURE [Common].[Update_Date]
#Status_ID int,
#Date_Value DATETIME OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF #Status_ID = 2
SET #Date_Value = GETDATE()
ELSE
SET #Date_Value = NULL
END
GO
When invoked from ADO.Net, you use ParameterDirection.Output. From T-SQL you invoke with an OUTPUT clause:
declare #date DATETIME;
exec [Common].[Update_Date] 2, #date OUTPUT;
SELECT #date;
In general is better not to mix procedure output with the return and with the result set (so that would be a vote against most other recommendation you got to use SELECT). Using OUTPUT makes procedures reusable from other T-SQL code, using result set (SELECT) makes it much harder to use as T-SQL has problems capturing the result set of an invoked procedure (you'd have to use INSERT ... SELECT and deal with all the problems that has).
RETURN values in Stored Procedures can only be integers. Therefore youre getting an error converting #Date_Value to an int
It looks like you need a Function, not a Stored Procedure
CREATE FUNCTION (Transact-SQL)
Alternatively, you can change RETURN to SELECT, but I would recommend using a FUNCTION for this type of request.
The return value from a stored procedure must be an integer. The RETURN #Date_Value line is throwing the error.
I believe the return value of a stored procedure is an integer, and your return statement is converting the datetime to int. Can you do a select instead to return the value?
SELECT #Date_Value
Here is a link on return values, output values, and result sets that you might find useful:
http://sqlserverpedia.com/wiki/Stored_Procedures_-_Output_Parameters_%26_Return_Values
You don't have to use "return" to return a value, you use "select" to return the value. Just change the RETURN keyword at the end of your SP and use SELECT and i will work.
The Return keyword must be used to return an integer. Try changing it to Select #Date_Value
You had a few problems. Try this:
CREATE PROCEDURE [Common].[Update_Date](
#Status_ID INT
) AS
SET NOCOUNT ON
BEGIN
--will #Date_Value have an initial value of NULL????
DECLARE #Date_Value DATETIME
SET #Date_Value = NULL
IF #Status_ID = 2 BEGIN
SET #Date_Value = GETDATE()
END
SELECT #Date_Value
END