Procedure or function 'Test' expects parameter '#ID', which was not supplied - sql

I am new to understanding stored procedures. I am dealing with one similar to this:
CREATE PROCEDURE [Test]
(
#ID int,
#month int,
#Low int,
#standard float = 0
)
AS
IF EXISTS (SELECT 1 FROM [Table1] WHERE ID = #ID AND
month = #month AND TYPE = 'S' AND TYPEID = #Low)
BEGIN
UPDATE [Table1] SET
Add = #standard
WHERE ID = #ID AND month = #month AND TYPE = 'S' AND TYPEID = #Low
END
ELSE
BEGIN
INSERT INTO [Table1] (ID, month, Add, TYPE, TYPEID)
VALUES (#ID, #month, #standard, 'S', #Low)
END
GO
Which runs from this table:
ID Month Add Type TypeID
333 feb 0 T 111
333 feb 4 S 111
333 feb -2 K 111
But i receive this error:
'Procedure or function 'Test' expects parameter '#ID', which was not supplied.'
When i try and execute the procedure
Can someone advise me on whats going on here with the error here and what i can do to fix it? I have included ID so im not quite sure why that is creating an error. thanks
I call the procedure like this:
USE [DB1]
GO
DECLARE #return_value int
EXEC #return_value = [Test]
SELECT 'Return Value' = #return_value
GO

Do this: In SQL Server Management Studio, in the Object Explorer pane, right click on your stored procedure and choose "Script Stored Procedure as ->", "EXECUTE To ->", and then "New Query Editor Window". This will build a SQL statement for you that will properly execute your stored procedure when supplied with the proper parameter values.

Related

Code a SQL Server stored procedure to update vc_statusID

I coded a stored procedure called vc_FinishVidCast that accepts an int as an input parameter that will be a vc_VidCastID that we will need to mark as finished. The act of finishing a VidCast means we must change its EndDateTime to be the current Date and Time (think GetDate()) and change the vc_StatusID to the vc_StatusID for the ‘Finished’ status.
alter procedure vc_FinishVidCast
(#vidCastID int, #finished int)
as
begin
update vc_VidCast
set vc_StatusID = #finished
where vc_VidCastID = #vidCastID
end
go
exec vc_FinishVidCast '859', '2'
DECLARE #newVC INT
INSERT INTO vc_VidCast (VidCastTitle, StartDateTime, ScheduleDurationMinutes, vc_UserID,vc_StatusID)
VALUES ('Finally done with sprocs', DATEADD(n, -45, GETDATE()), 45,
(SELECT vc_UserID FROM vc_User WHERE UserName = 'tardy'),
(SELECT vc_StatusID FROM vc_Status WHERE StatusText='Started')
)
SET #newVC = ##identity
SELECT *
FROM vc_VidCast
WHERE vc_VidCastID = #newVC
EXEC vc_FinishVidCast #newVC
SELECT * FROM vc_VidCast WHERE vc_VidCastID = #newVC
I get an error:
Msg 201, Level 16, State 4, Procedure vc_FinishVidCast, Line 179
Procedure or function 'vc_FinishVidCast' expects parameter '#finished', which was not supplied.
You may want to try something like below:
DECLARE #Finished_ID INT
SELECT #Finished_ID = vc_StatusID FROM vc_Status WHERE StatusText='FInished'
EXEC vc_FinishVidCast #newVC,#Finished_ID

SQL server stored procedure return a table

I have a stored procedure that takes in two parameters. I can execute it successfully in Server Management Studio. It shows me the results which are as I expect. However it also returns a Return Value.
It has added this line,
SELECT 'Return Value' = #return_value
I would like the stored procedure to return the table it shows me in the results not the return value as I am calling this stored procedure from MATLAB and all it returns is true or false.
Do I need to specify in my stored procedure what it should return? If so how do I specify a table of 4 columns (varchar(10), float, float, float)?
A procedure can't return a table as such. However you can select from a table in a procedure and direct it into a table (or table variable) like this:
create procedure p_x
as
begin
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t values('a', 1,1,1)
insert #t values('b', 2,2,2)
select * from #t
end
go
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t
exec p_x
select * from #t
I do this frequently using Table Types to ensure more consistency and simplify code. You can't technically return "a table", but you can return a result set and using INSERT INTO .. EXEC ... syntax, you can clearly call a PROC and store the results into a table type. In the following example I'm actually passing a table into a PROC along with another param I need to add logic, then I'm effectively "returning a table" and can then work with that as a table variable.
/****** Check if my table type and/or proc exists and drop them ******/
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'returnTableTypeData')
DROP PROCEDURE returnTableTypeData
GO
IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = 'myTableType')
DROP TYPE myTableType
GO
/****** Create the type that I'll pass into the proc and return from it ******/
CREATE TYPE [dbo].[myTableType] AS TABLE(
[someInt] [int] NULL,
[somenVarChar] [nvarchar](100) NULL
)
GO
CREATE PROC returnTableTypeData
#someInputInt INT,
#myInputTable myTableType READONLY --Must be readonly because
AS
BEGIN
--Return the subset of data consistent with the type
SELECT
*
FROM
#myInputTable
WHERE
someInt < #someInputInt
END
GO
DECLARE #myInputTableOrig myTableType
DECLARE #myUpdatedTable myTableType
INSERT INTO #myInputTableOrig ( someInt,somenVarChar )
VALUES ( 0, N'Value 0' ), ( 1, N'Value 1' ), ( 2, N'Value 2' )
INSERT INTO #myUpdatedTable EXEC returnTableTypeData #someInputInt=1, #myInputTable=#myInputTableOrig
SELECT * FROM #myUpdatedTable
DROP PROCEDURE returnTableTypeData
GO
DROP TYPE myTableType
GO
Consider creating a function which can return a table and be used in a query.
https://msdn.microsoft.com/en-us/library/ms186755.aspx
The main difference between a function and a procedure is that a function makes no changes to any table. It only returns a value.
In this example I'm creating a query to give me the counts of all the columns in a given table which aren't null or empty.
There are probably many ways to clean this up. But it illustrates a function well.
USE Northwind
CREATE FUNCTION usp_listFields(#schema VARCHAR(50), #table VARCHAR(50))
RETURNS #query TABLE (
FieldName VARCHAR(255)
)
BEGIN
INSERT #query
SELECT
'SELECT ''' + #table+'~'+RTRIM(COLUMN_NAME)+'~''+CONVERT(VARCHAR, COUNT(*)) '+
'FROM '+#schema+'.'+#table+' '+
' WHERE isnull("'+RTRIM(COLUMN_NAME)+'",'''')<>'''' UNION'
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #table and TABLE_SCHEMA = #schema
RETURN
END
Then executing the function with
SELECT * FROM usp_listFields('Employees')
produces a number of rows like:
SELECT 'Employees~EmployeeID~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("EmployeeID",'')<>'' UNION
SELECT 'Employees~LastName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("LastName",'')<>'' UNION
SELECT 'Employees~FirstName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("FirstName",'')<>'' UNION
You can use an out parameter instead of the return value if you want both a result set and a return value
CREATE PROCEDURE proc_name
#param int out
AS
BEGIN
SET #param = value
SELECT ... FROM [Table] WHERE Condition
END
GO
I had a similar situation and solved by using a temp table inside the procedure, with the same fields being returned by the original Stored Procedure:
CREATE PROCEDURE mynewstoredprocedure
AS
BEGIN
INSERT INTO temptable (field1, field2)
EXEC mystoredprocedure #param1, #param2
select field1, field2 from temptable
-- (mystoredprocedure returns field1, field2)
END
The Status Value being returned by a Stored Procedure can only be an INT datatype. You cannot return other datatypes in the RETURN statement.
From Lesson 2: Designing Stored Procedures:
Every stored procedure can return an integer value known as the
execution status value or return code.
If you still want a table returned from the SP, you'll either have to work the record set returned from a SELECT within the SP or tie into an OUTPUT variable that passes an XML datatype.
HTH,
John
Though this question is very old but as a new in Software Development I can't stop my self to share what I have learnt :D
Creation of Stored Procedure:
CREATE PROC usp_ValidateUSer
(
#UserName nVARCHAR(50),
#Password nVARCHAR(50)
)
AS
BEGIN
IF EXISTS(SELECT '#' FROM Users WHERE Username=#UserName AND Password=#Password)
BEGIN
SELECT u.UserId, u.Username, r.UserRole
FROM Users u
INNER JOIN UserRoles r
ON u.UserRoleId=r.UserRoleId
END
END
Execution of Stored Procedure:
(If you want to test the execution of Stored Procedure in SQL)
EXEC usp_ValidateUSer #UserName='admin', #Password='admin'
The Output:
create procedure PSaleCForms
as
begin
declare
#b varchar(9),
#c nvarchar(500),
#q nvarchar(max)
declare #T table(FY nvarchar(9),Qtr int,title nvarchar (max),invoicenumber nvarchar(max),invoicedate datetime,sp decimal 18,2),grandtotal decimal(18,2))
declare #data cursor
set #data= Cursor
forward_only static
for
select x.DBTitle,y.CurrentFinancialYear from [Accounts Manager].dbo.DBManager x inner join [Accounts Manager].dbo.Accounts y on y.DBID=x.DBID where x.cfy=1
open #data
fetch next from #data
into #c,#b
while ##FETCH_STATUS=0
begin
set #q=N'Select '''+#b+''' [fy], case cast(month(i.invoicedate)/3.1 as int) when 0 then 4 else cast(month(i.invoicedate)/3.1 as int) end [Qtr], l.title,i.invoicenumber,i.invoicedate,i.sp,i.grandtotal from ['+#c+'].dbo.invoicemain i inner join ['+#c+'].dbo.ledgermain l on l.ledgerid=i.ledgerid where (sp=0 or stocktype=''x'') and invoicetype=''DS'''
insert into #T exec [master].dbo.sp_executesql #q
fetch next from #data
into #c,#b
end
close #data
deallocate #data
select * from #T
return
end
Here's an example of a SP that both returns a table and a return value. I don't know if you need the return the "Return Value" and I have no idea about MATLAB and what it requires.
CREATE PROCEDURE test
AS
BEGIN
SELECT * FROM sys.databases
RETURN 27
END
--Use this to test
DECLARE #returnval int
EXEC #returnval = test
SELECT #returnval

Check stored procedure return value

A stored procedure is returning values like :
Text Value
sdsd 555
dsaa 544
swewe 745
And if it fails, it's returning like :
Standard
No Records Fouond
How can I distinguish among this 2 results in SQL query level?
Note : I can not modify the stored procedure
use the output of proc to find out that.
IF EXISTS(
SELECT name
FROM sysobjects
WHERE name = N'Pr_Test'
AND type = 'P' )
DROP PROCEDURE Pr_Test
GO
Create Procedure Pr_Test
(
#output BIT=0
)
As
BEGIN
SET NOCOUNT ON
IF #output = 0
SELECT 'No Records Fouond' AS [STANDARD]
ELSE
SELECT 'abc' AS [text], 1 AS [VALUE]
SET NOCOUNT OFF
END
Go
SET NOCOUNT ON
DECLARE #ProcOutput TABLE
(
column1 sysname NOT NULL
)
INSERT INTO #ProcOutput(Column1)
EXEC Pr_Test
IF EXISTS (SELECT TOP 1 1 FROM #ProcOutput WHERE column1='No Records Fouond')
PRINT ' this is failed select from proc'
ELSE
PRINT 'proc has some results'
SET NOCOUNT OFF

Can Someone look at my Stored Procedure and tell me where i am going wrong?

I'm writing an app and I'm generating a random order number in C# and before I do an insert statement I need to verify that there is no duplicate order number. This is my stored procedure (it's just a test procedure to help in figuring this out)
CREATE PROCEDURE Test$For$Dupes
(#RandNum int)
AS
declare #myNum int
SELECT OrderNumber, COUNT(*)
FROM [TEST]
WHERE OrderNumber = #RandNum
IF(COUNT(*) < 1)
SET #myNum = 0
IF(COUNT(*) > 1)
SET #myNum = 1
What I am trying to accomplish is if there is a duplicate I need to output a 1 and let my c# code regenerate a random number, and if there is no duplicate then I need an output of 0 so I can continue on my insert into my table.
I had this figured out a few years ago and can't find my code with how I did it, and now I am lost trying to figure this out. Any ideas?
It's not working just yet, I'm getting this error:
Msg 8120, Level 16, State 1, Procedure Test$For$Dupes, Line 8
Column 'TEST.OrderNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
This is a little more efficient because it stops looking thru the table when it finds a match. And I think it is clearer.
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
IF EXISTS (SELECT 1 FROM [TEST] WHERE OrderNumber = #RandNum)
SELECT 1
ELSE
SELECT 0
END
You would read this on the C# side like:
using (SqlConnection cnn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test$For$Dupes";
cmd.Parameters.AddWithValue("#RandNum", 100);
return (int) cmd.ExecuteScalar()
}
You don't even need the if..else condition, you can just use the following code:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
declare #myNum int
SELECT #myNum = CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM test
WHERE orderNumber = #RandNum
GROUP BY orderNumber
END
fiddle:http://sqlfiddle.com/#!3/51a0e/22
In your code, you are trying to compare in if condition as Count(*) which is not a variable..
you need to declare a variable and set that variable in the query then compare that variable in an if condition. So if i rectify your code it will be:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
Begin
declare #myNum int
declare #orderNoCount int
select #orderNoCount=COUNT(*) FROM [TEST]
WHERE OrderNumber = #RandNum
IF(#orderNoCount =< 1)
Set #myNum = 0
IF(#orderNoCount > 1)
SET #myNum = 1
END
in your code you are missing condition when ordernumber = 1... So I have added that condition too.
You can try this also:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
IF (select Count(Distinct OrderNumber) FROM [TEST] WHERE OrderNumber = #RandNum) >= 1
Set #myNum = 1
ELSE
SET #myNum = 0
END

T-SQL error object exists when separated in if/else blocks

I get the error: Msg 2714, Level 16, State 1, Line 16
There is already an object named '#mytemptable' in the database.
There are ways around it, but wonder why this happens. Seems like SQL Server is verifying both blocks of the if/else statement?
declare #choice int
select #choice = 1
if #choice = 1
begin
select 'MyValue = 1' AS Pick into #my_temp_table
end
else
begin
select 'MyValue <> 1' AS Pick into #my_temp_table
end
select * from #my_temp_table
drop table #my_temp_table
If the tables have different names, it works. Or if I create the temp table and use Insert Into... statements that works as well.
See here: What is deferred name resolution and why do you need to care?
basically you need to ceate the table first
So what is happening is that beginning with SQL server 7 deferred name resolution was enabled for real tables but not for temporary tables. If you change the code to use a real table instead of a temporary table you won’t have any problem
Here is another way
declare #choice int
select #choice = 1
declare #Value varchar(100)
if #choice = 1
select #Value = 'MyValue = 1'
else
select #Value = 'MyValue <> 1'
select #Value AS Pick into #my_temp_table
select * from #my_temp_table
drop table #my_temp_table
Try this:
declare #choice int
select #choice = 1
CREATE TABLE #my_temp_table(
Pick varchar(25)
)
if #choice = 1
begin
INSERT INTO #my_temp_table
select 'MyValue = 1'
end
else
begin
INSERT INTO #my_temp_table
select 'MyValue <> 1'
end
select * from #temptable
drop table #temptable
EDIT Sorry, I see that you tried this and the question was WHY does this happen. It is because SQL Server parses the stored procedure when it is created and checks for naming conflicts.