Procedure or function has too many arguments SQL server - sql

I getting this error while executing the stored procedure in SQL Server:
Msg 8144, Level 16, State 2, Procedure sp_adduser, Line 2
Procedure or function sp_adduser has too many arguments specified.
The weird thing is that the number of parameters is the same as declared in the procedure, even when I execute it while right-click on the procedure and press execute, input the parameters from the fields and still the same error.
This is the code of the procedure and the exec:
create procedure [dbo].[sp_addUser]
(
#userID nvarchar(50),
#pw nvarchar(50),
#fName nvarchar(50),
#lname nvarchar(50),
#email nvarchar(150),
#address nvarchar(150),
#city int,
#country int,
#phone nvarchar(50),
#gender nvarchar(10),
#dob date,
#photo nvarchar(150),
#secq int,
#secAnswer nvarchar(150),
#completed int output)
as
declare #found int
/*
usertype:
0 - Administrator
1 - User
*/
begin
begin
select #found=count(*) from registration r
where REPLACE(r.firstname,' ','')=REPLACE(#fName,' ','')
and REPLACE(r.lastname,' ','')=REPLACE(#lname,' ','')
and r.dateofbirth=#dob;
end
begin
if #found=0
begin
begin
insert into Login values(#userID,#pw,0,1);
end
begin
insert into registration values(
#userID,#fName,#lname,#email,
#address,#city,#country,#phone,
#gender,#dob,#photo,#secq,#secAnswer
)
end
begin
set #completed=1;
end
end
else set #completed=0
end
return #completed
end
And here is the exec:
DECLARE #return_value int,
#completed int
SELECT #completed = 0
EXEC #return_value = [dbo].[sp_addUser]
#userID = N'a',
#pw = N'a',
#fName = N'a',
#lname = N'a',
#email = N'a',
#address = N'a',
#city = 1,
#country = 1,
#phone = N'a',
#gender = N'a',
#dob = '01/01/2000',
#photo = N'a',
#secq = 1,
#secAnswer = N'a',
#completed = #completed OUTPUT
SELECT #completed as N'#completed'
SELECT 'Return Value' = #return_value
Thanks in advance!

sp_adduser is a procedure which is built-in to SQL Server - see https://msdn.microsoft.com/en-us/library/ms181422.aspx
Don't use the sp_ prefix for your own stored procedures, maybe call it proc_adduser instead, I think that will work

You are actually calling the system stored procedure sp_adduser. The "sp_" prefix is special and has its own rules on resolution, so using it is recommended against. If you want to use your own prefix, whatever you do, don't use "sp_".
Per #marc_s, even if your stored procedure doesn't clash with an existing system stored procedure, you will still get a noticeable performance hit due to cache misses.

Related

Operand Type Clash - SQL Server INSERT stored procedure

I understand the error, I am simply not sure why this is occurring. I have written a simple insert procedure to update a list of users.
Error:
Msg 206, Level 16, State 2, Procedure addNewUser, Line 0 [Batch Start Line 2]
Operand type clash: int is incompatible with date
Procedure declaration:
CREATE PROCEDURE [dbo].[addNewUser]
#fName VARCHAR(255),
#lname VARCHAR(255),
#dob DATE,
#email VARCHAR(255),
#gender VARCHAR(255),
#level VARCHAR(255) AS
INSERT INTO [dbo].[User] ([firstname], [lastname], [dob], [email], [gender], [accesslevel])
VALUES ('#fName ', N'#lname', #dob, N'#email', N'#gender', N'#level')
Calling procedure:
DECLARE #return_value int
EXEC #return_value = [dbo].[addNewUser]
#fName = N'Ste',
#lname = N'King',
#dob = 19780103,
#email = N'Books#email.com',
#gender = N'Male',
#level = N'Free'
SELECT 'Return Value' = #return_value
GO
Just put #dob = 19780103 into quotes '1978-01-03':
USE [t7068097]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[addNewUser]
#fName = N'Ste',
#lname = N'King',
#dob = '1978-01-03',
#email = N'Books#email.com',
#gender = N'Male',
#level = N'Free'
SELECT 'Return Value' = #return_value
GO
UPDATE:
SELECT CAST('1978-1-1' AS DATE)
SELECT CAST('19780101' AS DATE)
First your procedure is wrong. You shouldn't put your variables into the single quote for your purpose:
ALTER PROCEDURE [dbo].[addNewUser]
#fName varchar(255),
#lname varchar(255),
#dob DATE,
#email varchar(255),
#gender varchar(255),
#level varchar(255)
AS
INSERT [dbo].[User]
(
[firstname]
, [lastname]
, [dob]
, [email]
, [gender]
, [accesslevel]
)
VALUES
(
#fName
, #lname
, #dob
, #email
, #gender
, #level
)
GO
Also you send int value to the date field. You need yo put into the single quote:
DECLARE #return_value int
EXEC #return_value = [dbo].[addNewUser]
#fName = N'Ste',
#lname = N'King',
#dob = '19780103',
#email = N'Books#email.com',
#gender = N'Male',
#level = N'Free'
SELECT 'Return Value' = #return_value

Transaction count after EXECUTE indicates mismatching number of BEGIN and COMMIT statements

When I execute the below stored procedure I get this error:
System.Data.SqlClient.SqlException: Transaction count after EXECUTE
indicates a mismatching number of BEGIN and COMMIT statements.
Previous count = 0, current count = 1.
Code:
create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
if not exists (select emailid,phone from crm_masterdata where emailid=#Email And phone=#Mobile)
begin
begin transaction
declare #small smalldatetime = (select CAST(#Dob as smalldatetime))
declare #todaydate datetime=(select getdate())
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
Set #Message=' Registration Successfull,Please Login'
end
else
begin
set #Message='This User Already Registered'
end
end
Where is my error?
create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
SET NOCOUNT ON;
declare #small smalldatetime = (select CAST(#Dob as smalldatetime));
declare #todaydate datetime=getdate();
declare #Error INT;
BEGIN TRANSACTION; --<-- You need to commit it
IF not exists (select 1 from crm_masterdata where emailid=#Email And phone=#Mobile)
BEGIN
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid
,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification
,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
SET #Error = ##ERROR;
Set #Message =' Registration Successfull,Please Login'
END
ELSE
BEGIN
SET #Message='This User Already Registered'
END
IF (#Error = 0)
COMMIT TRANSACTION; --<-- Commit tran
ELSE
ROLLBACK TRANSACTION;
END
I don't see a COMMIT TRANSACTION to match your BEGIN TRANSACTION.

how to late parameter bind to dynamic sql statement in a stored procedure

I am attempting to dynamically build a T-SQL statement based on a FieldMapping table and some business rules.
Cut the long story short, I have a function that will return the SQL statement as a varchar(max) that I will execute as EXEC (#Sql) in my stored procedure.
Allow me to demonstrate with a test table
create procedure [dbo].[sp_TestInsert]
(
#Id int,
#Name varchar(20),
#Surname varchar(20),
#Age int,
#Source varchar(1)
)
as
declare #sql varchar(max)
-- Return SQL statement that depends on business rules
-- i.e. if the #Source = 'i' the returned SQL will be:
-- "update TestTable set Name = #Name, Surname = #Surname, SONbr = #SONbr WHERE Id = #Id"
-- however if the #Source = 'a' the returned SQL will be
-- "update TestTable set Name = #Name, Surname = #Surname, SONbr = #SONbr, Age = #Age WHERE Id = #Id"
-- As you can see, in case of 'i', it will NOT return Age = #Age
set #sql = dbo.func_UpdateOrInsert('TestTable', #Source)
-- When this statement is executed, the error I get is 'scalar #Name does not exist'
exec (#sql)
I've commented on the operation.
The problem is obvious, I would have expected that #Id, #Name, #Surname etc... would bind automatically to the corresponding field names [Id], [Name], [Surname] etc in the context of the stored procedure... however, this is not the case.
Is there any way I can bind the parameters to a dynamically built SQL statement?
The sp_executesql stored procedure does this
create procedure [dbo].[sp_TestInsert]
#Id int,
#Name varchar(20),
#Surname varchar(20),
#Age int,
#Source varchar(1)
as
declare
#sql nvarchar(max) = dbo.func_UpdateOrInsert('TestTable', #Source),
#params nvarchar(max)
= N'#Name varchar(20), #Surname varchar(20), #SONbr int, #Age int'
-- You need to get #SONbr from somewhere
exec sp_executesql #sql, #params, #Name, #Surname, #SONbr, #Age
-- note, it doesn't matter if a bound parameter isn't mentioned in the query
-- so #Age can be passed in regardless.

SQL call a SP from another SP

Can I please have some help with the syntax of a SP in SQL.
Here is my code:
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
Set #v_Value = usp_GetValue(#ID, #Description)
END
In the usp_InsertValue SP, I am wanting to declare and set a variable. Once the variable has been declared, I then wish to call another SP with parameters to set the value of the declared variable.
I am not sure of the syntax. May I please have some help?
UPDATE
I have updated my above code using your function. How do I Set the #v_Value from the usp_GetValue function.
I am getting this error:
'usp_GetValue' is not a recognized built-in function name.
UPDATE2
Here is my full code:
CREATE PROCEDURE usp_PersonCategoryLookupTesting
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertPersonTesting
(
#IDTest VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#AddressLine1 VARCHAR(50),
#AddressLine2 VARCHAR(50),
#AddressLine3 VARCHAR(50),
#MobilePhone VARCHAR(20),
#HomePhone VARCHAR(20),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #PersonCategory VARCHAR(15)
EXEC usp_PersonCategoryLookupTest #ID, #Description, #PersonCategory
INSERT INTO Person(FirstName, LastName, AddressLine1, AddressLine2, AddressLine3, MobilePhone, HomePhone, DateModified, PersonCategory, Comment)
VALUES (#FirstName, #LastName, #AddressLine1, #AddressLine2, #AddressLine3, #MobilePhone, #HomePhone, GETDATE (), #PersonCategory, #Comment)
END
I am getting this error in my application that is calling the SQL code:
Conversion failed when converting the varchar value '123Client' to data type int.
I am using the values "123" and "Client" for #IDTest and #Description.
I think output parameters should be the proper way:
See this post:
stored procedure returns varchar
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
EXEC usp_GetValue #ID, #Description, #v_Value
-- use #v_Value here...
END
You can only use a function like that, not stored procedure. Stored Procedures only return integer values.
For SP, you need to create out parameters to retrieve the values. For this scenario, it is better to create a function
CREATE FUNCTION usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
)
RETURNS VARCHAR(50)
AS
BEGIN
return #ID + #Description
END
Then call it:
SET #v_value = dbo.usp_GetValue('John','Doe') --output: John Doe
If you insist you want a SP, which is not proper for this, there are 2 ways
1) An out parameter
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#Result varchar(20) OUTPUT
)
AS
BEGIN
SET #Result = #ID + #Description
END
Then call it:
Declare #v_Value VARCHAR(15)
Set #v_Value = EXEC usp_GetValue #ID, #Description, #v_Value OUTPUT
2) Select from it
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
SELECT #ID + #Description
END
Use it like this:
declare #tempresult as table(v_value as varchar(15))
INSERT INTO #tempresult
EXEC usp_GetValue #ID, #Description
Select Top 1 #v_value = v_value From #tempresult
My advise is use the function approach.

SQL Server: Return uniqueidentifier from stored procedure

Can I return UNIQUEIDENTIFIER from a stored procedure using the RETURN statement or is it only by using the OUTPUT statement?
i.e to return the PersonID UNIQUEIDENTIFIER:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT
AS
DECLARE #Count INT
DECLARE #JobFileGUID UNIQUEIDENTIFIER
-- Check if job exists?
SET #Count = (SELECT COUNT(Name) AS Name FROM Person WHERE Name=#Name)
IF #Count < 1
BEGIN
SET #PersonGUID = NEWID();
INSERT INTO Person
(PersonID, Name, [Desc])
VALUES (#PersonGUID, #Name, #Desc)
END
SELECT #PersonGUID = Person.PersonID
FROM Person
WHERE Name = #Name
RETURN #PersonGUID
GO
Thanks
In stored procedure - only using the OUTPUT statement. In function - return.
Use:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT,
#PersonGUID UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #PersonGUID = ...
END
How to call:
DECLARE
#name NVARCHAR(255),
#desc TEXT,
#personGUID UNIQUEIDENTIFIER
SET #name = 'Bob'
SET #desc = 'One handsome man.'
EXEC [Database].[schema].CreatePerson #name, #desc, #personGUID OUTPUT
From the documentation you can actually see that a return in a stored procedure is actually used as a response code, hence you get the exception when trying to return a uniqueidentifier.
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-ver16#return-data-using-a-return-code
How I solved it, is by just performing a SELECT after the insert of the generated unique identifier.
DECLARE #ReportId UNIQUEIDENTIFIER;
SET #ReportId = NEWID();
INSERT INTO [dbo].[Report]
([ReportId]
,[ReportName])
VALUES
(#ReportId
,#ReportName)
SELECT #ReportId as ReportIdInternal
You'll have to see how to perform that with multiple selects though.
CREATE TABLE [dbo].[tbl_Clients]( [ClientID] [uniqueidentifier] NULL, [ClientName] varchar NULL, [ClientEnabled] [bit] NULL ) ON [PRIMARY]
GO
CREATE PROCEDURE [dbo].[sp_ClientCreate] #in_ClientName varchar(250) = "New Client 123", #in_ClientEnabled bit, #out_ClientId uniqueidentifier OUTPUT AS
SET #out_ClientId = NEWID();
INSERT INTO tbl_Clients(ClientId, ClientName, ClientEnabled) VALUES( #out_ClientId, #in_ClientName, #in_ClientEnabled)
DECLARE #return_value int, #out_ClientId uniqueidentifier
EXEC #return_value = [dbo].[sp_ClientCreate] #in_ClientName = N'111', #in_ClientEnabled = 1, #out_ClientId = #out_ClientId OUTPUT
SELECT #out_ClientId as N'#out_ClientId'
SELECT 'Return Value' = #return_value
GO
Result:-59A6D7FE-8C9A-4ED3-8FC6-31A989CCC8DB