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
Related
I am getting stuck in a situation, where I am creating a table and according to the table i want to create a procedure, but its showing an error.
I will provide snaps of that errors and i will provide table structure and proc structure:
Please help.. thank you
Table :
create table Students_Table
(
Student_ID bigint not null,
Student_Name nvarchar(50) not null,
Student_Enrollment_No bigint not null,
Student_Library_ID bigint,
Student_Gender nvarchar(15) not null,
Student_Phone nvarchar(15) not null,
Student_Email nvarchar(100) not null,
Student_Division nvarchar(30) not null,
Student_Current_Semester nvarchar(20) not null,
Student_Password nvarchar(80) not null,
Photo_Name nvarchar(MAX),
Photo_Size bigint,
Photo_Binary varbinary(MAX),
Username nvarchar(20),
Student_Address nvarchar(100),
Year nvarchar(10),
Shift nvarchar(10),
Roll_Number int,
Parents_Contact nvarchar(15)
);
Stored procedure:
create proc Insert_Student
#Student_Name nvarchar(50),
#Roll int,
#Student_Enrollment_No bigint,
#Student_Library_ID bigint,
#Student_Gender nvarchar(15),
#Student_Phone nvarchar(15),
#Student_Email nvarchar(100),
#Student_Division nvarchar(30),
#Student_Current_Semester nvarchar(20),
#Username nvarchar(20),
#Student_Address nvarchar(100),
#Student_Password nvarchar(80),
#Student_Shift nvarchar(10),
#Student_Year nvarchar(10),
#PContacts nvarchar(15),
#Photo_Name nvarchar(max),
#Photo_Size int,
#Photo_Binary varbinary(max),
#New_ID int output
as
begin
Insert into Students_Table
values (#Student_Name, #Student_Enrollment_No, #Student_Library_ID,
#Student_Gender, #Student_Phone, #Student_Email,
#Student_Division, #Student_Current_Semester, #Student_Password,
#Photo_Name, #Photo_Size, #Photo_Binary,
#Username, #Student_Address, #Student_Year, #Student_Shift,
#Roll, #PContacts)
select #New_ID = SCOPE_IDENTITY();
end
This is the error I am getting :
Msg 213, Level 16, State 1, Procedure Insert_Student, Line 23 [Batch Start Line 80]
Column name or number of supplied values does not match table definition.
The number of columns in your insert query is not matching with the number of columns. So Specify the column names:
Insert into Students_Table (Student_Name ,Student_Enrollment_No,Student_Library_ID,...)
Values (#Student_Name,#Student_Enrollment_No, #Student_Library_ID, ... )
If you don't want to specify the column names, then the Student_ID should be specified as auto increment identity.
I think that the error its due to the difference in the values you are providing to insert. Your table requires 19 fields and you are providing 18. You need either to change the Id to make it autoincremental or provide the Id in your insert statement.
I need a little help with this. The stored procedure below doesn't seem to ever match exiting unique identifier
ALTER PROCEDURE [dbo].[spInsertUpdateThisStuff]
#Id uniqueidentifier OUTPUT,
#Content nvarchar(255)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #tAudit table (id uniqueidentifier)
IF EXISTS(SELECT * FROM [dbo].[myData] WHERE [ID] = #Id)
-- UPDATE
BEGIN
UPDATE [dbo].[myData]
SET [ID] = #ID,
[Content] = #Content
OUTPUT inserted.[ID] INTO #tAudit
WHERE [ID] = #Id
SELECT id FROM #tAudit
END
ELSE
BEGIN
-- INSERT
SET #ID = NEWID()
INSERT INTO [dbo].CBData ([ID], [Content])
OUTPUT inserted.[ID] INTO #tAudit
VALUES(#Id, #Content)
SELECT id FROM #tAudit
END;
SET #ID = (SELECT id FROM #tAudit);
END
the C#
cmd.Parameters.Add("#ID", SqlDbType.UniqueIdentifier).Value = (currentRecord.ID == null) ? Guid.Empty : currentRecord.ID;
cmd.Parameters["#ID"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
currentRecord.ID = Guid.Parse(cmd.Parameters["#ID"].Value.ToString());
It seems the first IF statement does not ever become true, but if test (SELECT * FROM [dbo].[myData] WHERE [ID] = #Id) with a the matching UID it comes back with data.
This statement is problematic,,
DECLARE #tAudit table (id uniqueidentifier)
IF EXISTS(SELECT * FROM [dbo].[myData] WHERE [ID] = #Id)
-- UPDATE
BEGIN
#id is an Output Parameter and is null by default and you are trying to check that..
basically NEWID() won't be duplicated,so update part is redundant
How are you declaring the parameter in your code? Is it ParameterDirection.Output?
Try changing it to ParameterDirection.InputOutput. Your SQL looks okay. And you can pass an input value to a parameter declared as OUTPUT in your stored procedure. So maybe it's just that ParameterDirection.
You can also change this
IF EXISTS(SELECT * FROM [dbo].[myData] WHERE [ID] = #Id)
to
IF #Id IS NOT NULL AND EXISTS(SELECT * FROM [dbo].[myData] WHERE [ID] = #Id)
If your ID column isn't nullable then it's going to work the same either way. But this is a little more explicit, showing that it's recognized that #Id might be null because it's an OUTPUT parameter.
This is my fix.
This is my new stored procedure
ALTER PROCEDURE [dbo].[spInsertUpdatemyData]
#ID uniqueidentifier,
#IDOut uniqueidentifier OUTPUT,
#CONTENT nvarchar(255)
AS
BEGIN
--SET NOCOUNT ON;
DECLARE #tAudit table (outputID uniqueidentifier)
IF EXISTS(SELECT * FROM [dbo].[myData] WHERE [ID] = #ID)
-- UPDATE
BEGIN
UPDATE [dbo].[CBData]
SET [ID] = #ID,
[Content] = #Content
OUTPUT inserted.[ID] INTO #tAudit
WHERE [ID] = #ID
SELECT outputID FROM #tAudit;
END
ELSE
BEGIN
-- INSERT
INSERT INTO [dbo].myData
([ID],[Content])
OUTPUT inserted.[ID] INTO #tAudit
VALUES(NEWID(),#Content);
SELECT outputID FROM #tAudit
END;
set #IDOut = (SELECT outputID FROM #tAudit);
END
and the relative C#
//Add Parameter for output to sql command then Change Direction of parameter
cmd.Parameters.Add("#IDOut", SqlDbType.UniqueIdentifier).Value = Guid.Empty ;
cmd.Parameters["#IDOut"].Direction = ParameterDirection.InputOutput;
cmd.ExecuteNonQuery();
currentRecord.ID = Guid.Parse(cmd.Parameters["#IDOut"].Value.ToString());
cmd.Transaction.Commit();
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
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.
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'