Procedure expects parameter which was not supplied in SQL - sql-server

I'm getting this error when accessing a stored procedure in SQL Server:
Procedure or function 'resetdata' expects parameter '#FirstName', which was not supplied.
This is my table:
CREATE TABLE dbo.Client
(
ClientID int IDENTITY(1,1) PRIMARY KEY NOT NULL,
FirstName VARCHAR(50) NOT NULL,
LastName VARCHAR(50) NOT NULL,
StreetAddress VARCHAR(50) NULL,
Suburb VARCHAR(15)NULL,
C_State VARCHAR(3) NULL, --CHECK (C_State IN ('QLD', 'NSW', 'VIC', 'TAS', 'SA', 'WA', 'NT', 'ACT')),
PostCode SMALLINT NOT NULL,
PhoneNumber VARCHAR(11) NULL,
);
GO
ALTER TABLE Client
ADD CONSTRAINT state_ CHECK (C_State IN ('QLD', 'NSW', 'VIC', 'TAS', 'SA', 'WA', 'NT', 'ACT')),
CONSTRAINT check_post_code CHECK ([PostCode] LIKE '[0-9][0-9][0-9][0-9]' or [PostCode] LIKE '[0-9][0-9][0-9]');
GO
This is my stored procedure:
CREATE PROCEDURE [dbo].[resetdata]
#FirstName varchar(50),
#LastName varchar(50),
#PostCode smallint
AS
BEGIN
INSERT INTO A1.dbo.Client (FirstName, LastName, PostCode)
VALUES(#FirstName, #LastName, #PostCode)
END;
GO
EXEC dbo.resetdata;
INSERT INTO Client(FirstName, LastName, PostCode)
VALUES ('F', 'L', 12345);

Error message means exactly what it says: your SP is expecting three arguments as declared.
This is your SP header definition:
create procedure [dbo].[resetdata]
#FirstName varchar(50),
#LastName varchar(50),
#PostCode smallint
Three arguments. None of them has default.
This is how you're attempting to execute it:
EXEC dbo.resetdata;
No arguments provided. This causes the error from your question. Pass arguments to avoid error message.
Couple of things:
if you will try to apply script of your SP to test database or another copy of your database, you will have to modify your first line with USE A1. I'd suggest to remove this line. Choose DB once you connect, then just run all scripts on current database
Insert INTO A1.dbo.Client - same note about different databases and one more - if you already defined database with USE A1 at the beginning of the script, why are you referring same DB explicitly? If your SP and table are supposed to be in same DB - don't specify DB.

There are a couple of issues here:
The EXEC procedure is not passing the parameters required.
There is a constraint on the Postcode that will fail with 12345.
The correct code to run your stored procedure would be:
EXEC [dbo].[resetdata]
#FirstName = 'F',
#LastName = 'L',
#PostCode = 123

Try this:
USE A1;
GO
create procedure [dbo].[resetdata]
#FirstName varchar(50),
#LastName varchar(50),
#PostCode smallint
AS
BEGIN
Insert INTO A1.dbo.Client (FirstName,LastName,PostCode)
VALUES(#FirstName,#LastName,#PostCode)
END;
GO
EXEC dbo.resetdata #FirstName='F', #LastName='L', #PostCode=12345
--INSERT INTO Client(FirstName,LastName,PostCode) VALUES ('F','L',12345); No need to this Insert
Note: In sample data, you are going to insert 12345 to PostCode column, So it seems that 5 digit numbers are valid, but you have check constraint that shows PostCode should be 3 or 4 digit length. If 5 digit is valid so pay attention to the PostCode column's data type as it's maximum value is 32767. So if you want to insert a record with PostCode greater than this value you will get an error. May be it would be better to define it as INT and control it's value via a Check Constraint and also change the current check constraint definition on this column.

Related

Stored procedure insert issues - multiple inserts

Can you help me with this stored procedure? My problem is: when I create an account, my stored procedure works perfectly, but when I create a second account in the table evidenta_stundenti_materii, my previous id of account gets doubled.
How many times does it insert when I create an account :
in tbl_utilizatori : once
in tbl_studenti: once
in tbl_evidenta_stundenti: the previous id and the current id are re-inserted when I create the 2nd account
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[insertAnewAccAndANewStudent]
(#email varchar(30),
#parola varchar(30),
#nume varchar(30),
#prenume varchar(30),
#adresa varchar(30),
#nrTelefon varchar(30),
#conectat bit,
#idRol int,
#idSpecializare varchar(30))
AS
BEGIN
INSERT INTO dbo.tbl_utilizatori (email, parola, nume, prenume, adresa, nr_telefon, conectat, id_rol)
VALUES (#email, #parola, #nume, #prenume, #adresa, #nrTelefon, #conectat, #idRol)
IF (#idRol = '1')
BEGIN
DECLARE #id_utilizator int = ##identity
INSERT INTO dbo.tbl_studenti
VALUES (#id_utilizator, #idSpecializare, '0', '1')
END
INSERT INTO dbo.[tbl.evidenta_stundeti_materii] (id_utilizator, id_materie, id_specializare)
SELECT a.id_utilizator, b.id_materie, a.id_specializare
FROM dbo.tbl_studenti a
INNER JOIN dbo.tbl_materii b ON a.id_specializare=b.id_specializare
WHERE a.id_specializare = #idSpecializare
END
Bad English, can provide ss for a better understand problem

Inserting into MS SQL DB with procedure not working

I've tried a lot of googling and following some tutorials. I'm using MS SQL and trying to make a simple User table and salt and hashing the password, haven't gotten to the salting part, yet.
The table looks like this:
CREATE TABLE dbo.[User] (
UserID INT IDENTITY(1,1) NOT NULL,
Email NVARCHAR(45) NOT NULL,
Password BINARY(64) NOT NULL,
FirstName NVARCHAR(45) NULL,
LastName NVARCHAR(45) NULL,
CONSTRAINT [PK_User_UserID] PRIMARY KEY CLUSTERED (UserID ASC)
)
And the procedure looks like this:
ALTER PROCEDURE dbo.[uspAddUser]
#pEmail NVARCHAR(45),
#pPassword NVARCHAR(45),
#pFirstName NVARCHAR(45) = NULL,
#pLastName NVARCHAR(45) = NULL,
#responseMessage NVARCHAR(250) OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
INSERT INTO dbo.[User] (Email, Password, FirstName, LastName)
VALUES (#pEmail, HASHBYTES('SHA_512', #pPassword), #pFirstName, #pLastName)
SET #responseMessage = 'Success'
END TRY
BEGIN CATCH
SET #responseMessage = ERROR_MESSAGE()
END CATCH
END
When I try to insert with the procedure it won't work:
DECLARE #responseMessage NVARCHAR(250)
EXEC dbo.[uspAddUser]
#pEmail = N'Admin#email.com',
#pPassword = N'123',
#pFirstName = N'Admin',
#pLastName = N'Administrator',
#responseMessage=#responseMessage OUTPUT
SELECT *
FROM [dbo].[User]
No results are shown. After inserting normally and then retrieving the results it shows the newly created tuple but with the ID auto incremented like other tuples were created. I'm not really sure where the problem is and would be grateful if someone else understood.
EDIT:
SOLVED
Apparently the fault was I used the wrong kind of sha hash. Instead of using SHA_512 I should've used SHA2_512.
HASHBYTES('SHA_512', #pPassword) returns null so that insert query gets aborted. Instead, you can use algorithms SHA2_512 or SHA2_256 or any other encryption algorithm you want.
Check out this link for more info.

SQL Server : parameterized stored procedure

I have to do this in SQL Server. Assume that I have 2 tables.
Based on parameters Name and Surname, I have to take PhysicianID from Table1.
After that I have to create new record using insert into stored procedure.
Something like this
CREATE PROCEDURE FIND_PHYSICIANID
#FirstName varchar(50),
#LastName varchar(50)
AS
BEGIN
DECLARE #PhysicianID int
SELECT #PhysicianID = PhysicianID
FROM Table1
WHERE FirstName = #FirstName AND LastName = #LastName
RETURN #PhysicianID
END
EXECUTE FIND_PHYSICIANID 'Kathlin','Jones'
CREATE PROCEDURE ADD_APPOINTMENT -- Create a new appointment
#AppointmentType VARCHAR(70), --Type of new appointment
#pAppointmentDate DATE, -- Date of new appointment
#aPhysicianID INT, --PhysicianID of requested physician (in this case during execution we will take value which we know-read from table for requested first and last name)
#apPatientID INT, --PatientID of chosen patient(let's say any from 1 to 14)
#aScheduleID INT, --ScheduleID, but here we have to take some ScheduleID for chosen PhysicianID (in this case during execution we will take value which we know-based on PHYSICIANID we may read value from table SCHEDULE)
#Status CHAR(1) -- Just Y or N
AS -- This "AS" is required by the syntax of stored procedures.
BEGIN -- Insert the new appointment
INSERT INTO [APPOINTMENT]([AppointmentType], [AppointmentDate],[aPhysicianID],
[apPatientID], [aScheduleID], [Status-Canceled])
VALUES (#AppointmentType, #pAppointmentDate, #aPhysicianID,
#apPatientID, #aScheduleID, #Status);
END;
EXECUTE ADD_APPOINTMENT 'Vaccinations', '2017-0831', '#PhysicianID', '12', '289', 'N'
You can get return id like this.
DECLARE #PhysicianID int
EXECUTE #PhysicianID = FIND_PHYSICIANID 'Kathlin','Jones'
you can use this param like this
EXECUTE ADD_APPOINTMENT 'Vaccinations','2017-0831', #PhysicianID, '12','289','N'
Presuming that the ability to find a physician is a common operation you could convert the FIND_PHYSICIANID stored procedure to a function and delay the lookup to within the consuming stored procedure that performs the operation.
create function [dbo].[FIND_PHYSICIANID]
(
#FirstName varchar(50),
#LastName varchar(50)
)
returns int
as
begin
declare #PhysicianId int
select #PhysicianID = PhysicianID
from dbo.Table1
where FirstName = #FirstName
and LastName = #LastName
return #PhysicianId
end
This will still keep the logic of finding a physician centralised but allow you to perform other actions and possibly validation if the only information you have available to you is the full name. Yes, it is more parameters but this is assuming the required parameters for the stored procedures are a manageable amount.
create procedure [dbo].[ADD_APPOINTMENT] -- Create a new appointment
#AppointmentType VARCHAR(70), --Type of new appointment
#pAppointmentDate DATE, -- Date of new appointment
#PhysicianFirstName varchar(50), -- // The first name of the physician
#PhysicianLastName varchar(50), -- // The last name of the physician
#apPatientID INT, --PatientID of chosen patient(let's say any from 1 to 14)
#aScheduleID INT, --ScheduleID, but here we have to take some ScheduleID for chosen PhysicianID (in this case during execution we will take value which we know-based on PHYSICIANID we may read value from table SCHEDULE)
#Status CHAR(1) -- Just Y or N
AS -- This "AS" is required by the syntax of stored procedures.
BEGIN -- Insert the new appointment
declare #aPhysicianID int
select #aPhysicianID = [dbo].[FIND_PHYSICIANID](#PhysicianFirstName, #PhysicianLastName varchar(50))
INSERT INTO [APPOINTMENT]([AppointmentType], [AppointmentDate],[aPhysicianID],
[apPatientID], [aScheduleID], [Status-Canceled])
VALUES (#AppointmentType, #pAppointmentDate, #aPhysicianID,
#apPatientID, #aScheduleID, #Status);
END
Alternatively, if it is desired to be separated and keep the existing stored procedure parameter signature then the previous answer that has the caller lookup the physician id via the stored procedure locally and then pass that parameter into the add appointment stored procedure should suffice your requirements.
As per the below pseudocode
Declare a variable for #physicianid of type int
Assign the #physicianid variable to the output of the FIND_PHYSICIANID stored procedure
Execute ADD_APPOINTMENT stored procedure with #physicianid variable as an input

Null values stored in table via Stored Procedure

Following is my stored procedure which stores data in two tables namely SuccessfulLogins and FailedLogins
ALTER procedure [dbo].[Proc_CheckUser]
#UserID VARCHAR(50),
#Password VARCHAR(50)
AS
SET NOCOUNT ON
DECLARE #ReturnVal VARCHAR(500)
DECLARE #PasswordOld VARCHAR(50)
DECLARE #Type NVARCHAR(50)
DECLARE #IP NVARCHAR(50)
SELECT #PasswordOld = Password,#Type=ClientType,#IP=IPAddress
FROM Clients
WHERE Username = #userid
IF (#PasswordOld IS NULL)
BEGIN
SET #ReturnVal='1|Incorrect Username'
INSERT INTO FailedLogins(Username,Password,ClientType,Reason,IPAddress)
VALUES(#UserID,Hashbytes('SHA1',#Password),#Type,'Invalid Username',#IP)
END
ELSE
BEGIN
IF (#PasswordOld!=Hashbytes('SHA1',#Password))
BEGIN
SET #ReturnVal='1|Incorrect Password'
INSERT INTO FailedLogins(Username,Password,ClientType,Reason,IPAddress)
VALUES(#UserID,Hashbytes('SHA1',#Password),#Type,'Invalid Password',#IP)
END
ELSE
BEGIN
SET #ReturnVal='0|Logged in Successfully' +'|'+ rtrim(cast(#Type as char))
INSERT INTO SuccessfulLogins(Username,Password,ClientType,Reason,IPAddress)
VALUES(#UserID,Hashbytes('SHA1',#Password),#Type,'Valid Login Credentials Provided',#IP)
END
END
SELECT #ReturnVal
The problem here is that whenever I enter an Invalid Username,the stored procedure returns the correct message ie Incorrect Username but it stores NULL values in the fields ClientType and IPAddress in Failed Logins Table
Following is my insert query for Invalid username
IF (#PasswordOld!=Hashbytes('SHA1',#Password))
BEGIN
SET #ReturnVal='1|Incorrect Password'
INSERT INTO FailedLogins(Username,Password,ClientType,Reason,IPAddress)
VALUES(#UserID,Hashbytes('SHA1',#Password),#Type,'Invalid Password',#IP)
END
Can anyone help me to rectify this.How to check condition for username?
Thanks
Your code reads
SELECT #PasswordOld = Password,#Type=ClientType,#IP=IPAddress
FROM Clients
WHERE Username = #userid
Wouldn't this mean that no row will be returned for a Username that does not exist? So, the values for ClientType and IPAddress will not get populated and will remain NULL, which would be the expected functionality.
However, if you want to store some value, or these fields are not nullable, assign a static value to these parameters.
Your query is correct. When there is no match for the Username = #UserId , The #Type , #IP variables will be null. Since there is no record in the table for that UserName. What you can do is that in the declaration you can initiate to some default value,so that it will be inserted to table FailedLogins.
DECLARE #Type NVARCHAR(50)="DefaultType/NoType"
DECLARE #IP NVARCHAR(50)="0.0.0.1"
Something like the above.
If the username is invalid it does not appear in the table Clients so your fields pulled from that table will also be NULL. To negate this you could decide to use default values for ClientType and IPAddress using static values in your declarations, but storing this would just be obsolete data and I would think changing the structure of FailedLogins to not store this would seem more logical.

How to get data back from stored procedure

I'm trying to debug\execute a SP from t-sql (sql server 2008) and when I execute the following sql it returns only a message 'Command(s) completed successfully'.
I know the SP is returning the data in a table via the #RETURN_VALUE parameter, how do I get this to display in sql query window.
exec STARMS.dbo.GetMetaData ##Assembly=13366,##Namespace=NULL,##ParameterName=NULL,##Standard=0,##Timestamp=NULL
The SP looks something like this ( removed the main body) the interesting part is the creation of the temp table and then returning the contents of the temp table:
CREATE PROCEDURE [dbo].[GetMetaData]
##Assembly Sql_Variant = NULL,
##Namespace Varchar(30) = NULL,
##ParameterName Varchar(40) = NULL,
##Standard Bit = 0,
##Timestamp DateTime = NULL
AS
SET NOCOUNT ON
DECLARE #ResultTable TABLE (AssemblyId Int, Namespace Varchar(30), ParameterName Varchar(40), Value Varchar(100))
-- Does loads of stuff and then inserts into #ResultTable table...
SET NOCOUNT OFF
-- Return the result
SELECT AssemblyId, Namespace, ParameterName, [Value]
FROM #ResultTable
RETURN
Note: the reason I'm asking the question is because I'm trying to look at the performance of the SP in SQL Server 2008 and I'm unsure why this doesn't return the data in the query window.
Check your full code of SP, may be somewhere there is a RETURN statement, so - the SP will not return any data (pay attention on IF SomeContition IS TRUE RETURN):
CREATE PROCEDURE [dbo].[GetMetaData]
##Assembly Sql_Variant = NULL,
##Namespace Varchar(30) = NULL,
##ParameterName Varchar(40) = NULL,
##Standard Bit = 0,
##Timestamp DateTime = NULL
AS
SET NOCOUNT ON
DECLARE #ResultTable TABLE (AssemblyId Int, Namespace Varchar(30), ParameterName Varchar(40), Value Varchar(100))
-- Does loads of stuff and then inserts into #ResultTable table...
IF SomeContition IS TRUE RETURN
SET NOCOUNT OFF
-- Return the result
SELECT AssemblyId, Namespace, ParameterName, [Value]
FROM #ResultTable
RETURN

Resources