Initializing parameters in a stored procedure - c#

I am getting an exception when executing a stored procedure:
Procedure or function 'spAddItemByUrl' expects parameter '#userId', which was not supplied.
But I have initialized it, so what I'm dong wrong?
Here is the stored procedure:
create proc spAddItemByUrl
#title nvarchar(50),
#body nvarchar(50),
#link nvarchar(50),
#userName nvarchar(50),
#url nvarchar(50),
#userId int,
#feedId int
as
begin
insert into feed(title, body, link) values(#title, #body, #link)
select #userId = id from users where name = #userName
select #feedId = id from feed where title = #title
insert into userstofeed(userid, feedid) values(#userId, #feedId)
insert into feedurl(url, feedid, userid) values(#url, #feedId, #userId)
end
And here's the C# code.
The exception is thrown when I call ExecuteNonQuery:
connection.SqlCommand.Parameters.AddWithValue("#url", urlFeed.Url);
connection.SqlCommand.Parameters.AddWithValue("#title", item.Title.Text);
connection.SqlCommand.Parameters.AddWithValue("#body", item.Summary.Text);
connection.SqlCommand.Parameters.AddWithValue("#link", item.Id);
connection.SqlCommand.Parameters.AddWithValue("#userName", user);
connection.SqlCommand.ExecuteNonQuery();
connection.SqlCommand.Parameters.Clear();

You've added #userId int, #feedId int to the list of parameters for your SProc, but from the query it looks like you don't want them to be provided by the user. You can declare them inside the SProc to make them "local".
i.e.
create proc spAddItemByUrl
#title nvarchar(50),
#body nvarchar(50),
#link nvarchar(50),
#userName nvarchar(50),
#url nvarchar(50)
as
begin
DECLARE #userId int, #feedId int;
insert into feed(title, body, link) values(#title, #body, #link)
select #userId = id from users where name = #userName
select #feedId = id from feed where title = #title
insert into userstofeed(userid, feedid) values(#userId, #feedId)
insert into feedurl(url, feedid, userid) values(#url, #feedId, #userId)
end

You've specified
connection.SqlCommand.Parameters.AddWithValue("#userName", user);
but not #userid

If you want to add default values to your stored procedure arguments you can do the following:
create proc spAddItemByUrl
...
#userId int = 0, /* or whatever you want the default value to be */
#feedId int = 0
If you decide to call your stored procedure, you then only have to pass the five arguments provided in your code, and the values #userId and #feedId will be 0. If you decide to specify values for those two parameters in your calling function, then the values you pass will be used.
Since your stored procedure doesn't use those parameters though, you should remove them from the section they are in.
Instead just do
declare #userId int = select id from users where name = #userName
declare #feedId int = select id from feed where title = #title

Related

What is Best Approach for Auto Increament

I am building a Queue Management System in C# using Sql Server 2008 R2. Providing Services in many departments at a time Like Customer Care, Ladies Section, Registration Section. For Example. For
Ladies Section : Token {1-50}
Customer Care : Token {51-350}
Registration Section : Token {351-550}
Normal Customers: Token {551-999}
I am using this Approach, First of all i am looking from which department I am getting request. Check Token Range of this department in Table, then getting existing value of the Token for this department. Overriding existing value with Updating Next Number table.
Is there any other approach i can use because i am facing problem that sometimes same Token Number is coming on Two Screens of Normal Customer's/Registration/Customer/Ladies Sections.
Thanks
You could use update with output statement, like this:
use tempdb
go
if object_id('Tokens', 'u') is not null drop table Tokens
if object_id('GetNextToken', 'p') is not null drop procedure GetNextToken
go
create table Tokens (
Id int identity(1,1) not null,
Name varchar(50) not null,
TokenFrom int not null,
TokenTo int not null,
LastUsedToken int null,
constraint PK_Tokens primary key clustered (Id),
constraint UQ_Tokens_Name unique (Name)
)
go
insert into Tokens (Name, TokenFrom, TokenTo)
select 'Ladies Section', 1, 50 union
select 'Customer Care', 51, 350 union
select 'Registration Section', 351, 550 union
select 'Normal Customers', 551, 999
go
create procedure GetNextToken
#name varchar(50),
#token int output
as
begin
declare #tokens table (token int)
update Tokens
set LastUsedToken =
case
when LastUsedToken is null then TokenFrom
when LastUsedToken = TokenTo then TokenFrom
else LastUsedToken + 1
end
output inserted.LastUsedToken into #tokens
where Name = #name
set #token = (select top 1 token from #tokens)
end
go
-- To get 'Ladies Section'
declare #name varchar(50), #token int
set #name = 'Ladies Section'
exec GetNextToken #name, #token output
select #token
go
-- To get 'Customer Care'
declare #name varchar(50), #token int
set #name = 'Customer Care'
exec GetNextToken #name, #token output
select #token
go
-- To get 'Registration Section'
declare #name varchar(50), #token int
set #name = 'Registration Section'
exec GetNextToken #name, #token output
select #token
go
-- To get 'Normal Customers'
declare #name varchar(50), #token int
set #name = 'Normal Customers'
exec GetNextToken #name, #token output
select #token

Select Scope Identity from Sql

I am executing an Insert query. I want to return the identity element. I am also using this same stored procedure. Inside another stored procedure to return the identity element.
Alter Proc Proc1
#name varchar(10),
#value int
As
Begin
insert into Table1
values (#name, #value)
return SCOPE_IDENTITY()
C# code:
I have a method to call my database every time, so I use that
_database.StoredProcedure = "Proc1";
_database.parameter("name","michael");
_database.parameter("value",10);
int id = Convert.ToInt32(_database.ExecuteScalar());
Here, I get id=0 every time //BUG
SQL other stored procedure:
Alter Proc2
// Some other logic
Execute #id = Proc1 #name, #value // THIS WORKS
Now, If I change Proc1's last line to Select SCOPE_IDENTITY() from RETURN SCOPE_IDENTITY() then C# code works but Proc2 returns 0.
What should I do such that it works in C# code and in Proc2 also.
I thought about an output parameter, but I don't know how would I call it with my this database method in C#.
If you want data out of a procedure the correct thing is to use output parameters. Do NOT use the return_value from your procedures. This value indicates a status of the execution, not data from the procedure.
Here is an example of what this might look like.
Alter Proc Proc1
#name varchar(10),
#value int,
#IdentityValue int OUTPUT
As
Begin
insert into Table1 values (#name,#value)
Select #IdentityValue = SCOPE_IDENTITY()
END
select * from table1
GO
Alter Proc2
(
#name varchar(10)
, #value int
, #IdentityValue int OUTPUT
)
as
//SOme other logic
declare #IdentityValue int
Execute Proc1 #name, #value, #IdentityValue OUTPUT
GO
Also, please notice that you have an insert in Proc1 but you don't specify the columns. This is very bad practice. If your table structure changes your procedure is broken. You should ALWAYS specify the columns in your insert.
Change your procedure body to like below, to change the RETURN statement to SELECT SCOPE_IDENTITY()
Alter Proc Proc1
#name varchar(10),
#value int
As
Begin
insert into Table1 values (#name,#value);
SELECT SCOPE_IDENTITY();
END
In that case, make it a output parameter and set that output parameter to scope_identity
Alter Proc Proc1
#name varchar(10),
#value int,
#ID INT OUTPUT
As
Begin
insert into Table1 values (#name,#value);
SET #ID = SCOPE_IDENTITY();
END
You can call the procedure
cmd.Parameters.Add("#ID", SqlDbType.Int, 0, "ID");
cmd.Parameters["#ID"].Direction = ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
int id = (int)cmd.Parameters["#ID"].Value;

ADO.NET stored procedure for inserting not working

I have a database which stores information about a library (books, authors & categories).
But I can't get my stored procedure to work for inserting data. The stored procedure itself executes fine, but when I perform a test, it simply doesn't add anything to the database. Can anyone see what I'm missing?
This is my stored procedure (for category):
USE MyLibrary
GO
IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'CategoryInsert' AND TYPE = 'P')
BEGIN
DROP PROC CategoryInsert
END
GO
CREATE PROCEDURE CategoryInsert
(
#Id int out,
#Name nvarchar(255),
#InsertedBy nvarchar(120),
#InsertedOn datetime
)
AS
DECLARE #CurrentId int
SELECT #CurrentId = Id FROM Category WHERE lower(#Name) = lower(#Name)
IF #CurrentId IS NOT NULL
BEGIN
SET #Id = -100
RETURN
END
INSERT INTO Category
(
Name,
InsertedBy,
InsertedOn
)
VALUES
(
#Name,
#InsertedBy,
#InsertedOn
)
SET #Id = SCOPE_IDENTITY()
GO
This is my test:
USE MyLibrary
GO
DECLARE #NewId int
DECLARE #date datetime
SET #date = getdate()
EXEC CategoryInsert #NewId, 'Testing', 'AL', #date
SELECT #NewId
GO
This line:
SELECT #CurrentId = Id FROM Category WHERE lower(#Name) = lower(#Name)
IF #CurrentId IS NOT NULL
The equality check will always return true because you're essentially comparing WHERE 1 = 1, which means that #CurrentID will always have a value and thus your stored procedure will always return before the INSERT happens.

Return string via stored procedure using C#

I have a table which has a column that is being auto-generated based on other columns in the table. I am attempting to insert data into the table using a stored procedure and then return the auto-generate column. In the stored procedure below, #Num represents the auto-generated column.
The approach I am taking here works with regard to inserting the data into the database. What isn't working is returning #Num from the Insert stored procedure. Is what I am trying to do possible. If so what am I doing wrong? If not, is there an alternative method to accomplish this?
This is my C#. When I run this, returnValue comes back null.
internal static bool InsertApplication(Something something)
{
object returnValue;
string sql = "usp_InsertSproc";
returnValue = DatabaseFactory.CreateDatabase("ConnectionString").ExecuteScalar(sql, new Object[] { something.First_Name, something.Last_Name });
//I'd like to be able to access the #Num value from the Sproc here
}
This is my stored procedure:
ALTER PROCEDURE [dbo].[usp_InsertSproc]
(
#First_Name varchar(50),
#Last_Name varchar(50),
#Num Varchar(500) Output
)
AS
SET NOCOUNT OFF;
INSERT INTO [Table] ([First_Name], [Last_Name])
VALUES (#First_Name, #Last_Name, )
Return #Num
This is what my table looks like.
CREATE TABLE [Table]
(
[First_Name] VARCHAR(50),
[Last_Name] VARCHAR(50),
[Num] AS ([dbo].[SetCMP]([Num]))
)
I'm assuming your table looks something like this:
CREATE TABLE [Table]
(
[First_Name] VARCHAR(50),
[Last_Name] VARCHAR(50),
[Num] AS [First_Name] + [Last_Name] + '!'
)
Your C# should be fine. Change your stored procedure to something like:
ALTER PROCEDURE [dbo].[usp_InsertSproc]
#First_Name VARCHAR(50),
#Last_Name VARCHAR(50)
AS
SET NOCOUNT OFF;
INSERT INTO [Table] ([First_Name], [Last_Name])
OUTPUT inserted.[Num]
VALUES (#First_Name, #Last_Name)
GO
EXEC [dbo].[usp_InsertSproc]
#First_Name = 'Tom',
#Last_Name = 'Hunter'

SQL 2000: Stored Procedures Error : Procedure or Function 'name' expects parameter '#param', which was not supplied

I have a stored procedure which is declared as follows:
ALTER PROCEDURE dbo.thisProc
#ID int,#TypeID int, #DocID int, #Section varchar(10)
What I need is to be able to do this:
If #ID is supplied, execute a particular if block
if #ID is not supplied then move check if #TypeID is input and then execute another if block.
I don't want to write multiple sql queries to deal with different inputs/page sections that a user is viewing.
Thanks.
SAMPLE CODE:
CREATE PROCEDURE GetArticle
#ID int,#DoTypeID int, #DocID int, #Sec varchar(10)
AS
IF #ID IS NOT NULL AND , #DocID IS NOT NULL AND #Sec = 'inner'
BEGIN
SELECT "my query is here"
WHERE Articles.ID = #ID AND Articles.DocID = #DocID
END
ELSE IF #ID IS NULL AND #DocID IS NULL AND #Sec = 'list'
BEGIN
EXEC GetDocList #DocTypeID
END
ELSE IF #ID IS NULL AND #DocID IS NULL AND #Sec = 'full'
BEGIN
EXEC GetDocList #DocTypeID
END
Just give #id a default value of null. E.g.
#id int = null

Categories

Resources