Having a total blonde moment here so apologies in advance...!
I want to carry out two COUNT conditions prior to entering a new customer recorded into a DB. The below code checks to see if the Username is already in use and rejects the registration if this is applicable. I would like to add an additional COUNT to check if the "CustomerEmail", taken from txtEmail already exists in the DB as well.
I would use a stored procedure to do this something like....
And obviously use appropriate data types for the params
CREATE PROCEDURE usp_InsertUser
#FirstName VARCHAR(100)
, #Surname VARCHAR(100)
, #Email VARCHAR(100)
, #Address VARCHAR(100)
, #Town VARCHAR(100)
, #City VARCHAR(100)
, #Postcode VARCHAR(100)
, #ContactNumber VARCHAR(100)
, #Username VARCHAR(100)
, #Password VARCHAR(100)
, #UserAdded INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT *
FROM [Customer] WITH (UPDLOCK)
WHERE CustomerUserName = #Username)
BEGIN
INSERT INTO [Customer] (CustomerFirstName,CustomerSurname,CustomerEmailAddress,CustomerAddress,CustomerAddressTown,CustomerAddressCity,CustomerAddressPostcode,CustomerContactNumber,CustomerUserName,CustomerPassword)
VALUES (#FirstName, #Surname,#Email, #Address, #Town, #City, #Postcode,#ContactNumber,#Username,#Password)
SET #UserAdded = 1;
END
ELSE
BEGIN
SET #UserAdded = 0;
END
END
Application code would look something like.....
// define connection and command, in using blocks to ensure disposal
using(SqlConnection conn = new SqlConnection(pvConnectionString ))
using(SqlCommand cmd = new SqlCommand("dbo.usp_InsertUser", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// set up the parameters
cmd.Parameters.Add("#UserAdded", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.Parameters.Add("#FirstName", SqlDbType.VarChar, 100);
cmd.Parameters.Add("#Surname", SqlDbType.VarChar, 100);
cmd.Parameters.Add("#Email", SqlDbType.VarChar, 100);
// and so on.....
// set parameter values
cmd.Parameters["#FirstName"].Value = txtFirstName.Text;
cmd.Parameters["#Surname"].Value = txtSurname.Text;
cmd.Parameters["#Email"].Value = txtEmail.Text;
// and so on.....
// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();
// read output value from #NewId
int UserAdded = Convert.ToInt32(cmd.Parameters["#UserAdded"].Value);
if (UserAdded == 1)
{
Response.Write("User already exists.");
}
conn.Close();
}
Instead of counting all users and adding 2 check just do one exists statement with 2 conditions.
IF NOT EXISTS(select count(*) from [Customer] where CustomerUserName= #name AND CustomerEmail = #email)
BEGIN
INSERT INTO [Customer] (CustomerFirstName,CustomerSurname,CustomerEmailAddress,CustomerAddress,CustomerAddressTown,CustomerAddressCity,CustomerAddressPostcode,CustomerContactNumber,CustomerUserName,CustomerPassword) VALUES (#FirstName, #Surname,#Email, #Address, #Town, #City, #Postcode,#ContactNumber,#Username,#Password)
END
Related
This is my Users table:
CREATE TABLE [dbo].[users]
(
[user_id] INT IDENTITY (1, 1) NOT NULL,
[first name] NVARCHAR (50) NULL,
[last name] NVARCHAR (50) NULL,
[email] NVARCHAR (MAX) NULL,
[user_password] NVARCHAR (MAX) NULL,
[user_salt] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([user_id] ASC)
);
This is my FeedBack_T table:
CREATE TABLE [dbo].[FeedBack_T]
(
[FeedBack_Id] INT IDENTITY (1, 1) NOT NULL,
[firstname] NVARCHAR (50) NOT NULL,
[lastname] NVARCHAR (50) NOT NULL,
[email] NVARCHAR (50) NOT NULL,
[phone] NVARCHAR (50) NOT NULL,
[subject] NVARCHAR (50) NOT NULL,
[feedback_type] NVARCHAR (50) NOT NULL,
[comments] NVARCHAR (300) NOT NULL,
[yesOrNo] NVARCHAR (50) NOT NULL,
[user_id] INT NOT NULL,
PRIMARY KEY CLUSTERED ([FeedBack_Id] ASC),
CONSTRAINT [FK_FeedBack_T_Users]
FOREIGN KEY ([user_id]) REFERENCES [users]([user_id])
);
My SQL command
String CS = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
con.Open();
SqlCommand insert = new SqlCommand("INSERT INTO FeedBack_T VALUES('" + txtFeedbackName.Text + "','" + txtFeedbackLastName.Text + "','" + txtFeedbackEmail.Text + "','" + txtPhoneNumber.Text + "','" + txtFeedbackSubject.Text + "','" + ddFeedbackType.SelectedItem.Text + "','" + textAreaFeedback.InnerText + "','" + rdbText() + "')", con);
insert.ExecuteNonQuery();
insert.Dispose();
}
if (Page.IsValid)
{
Server.Transfer("feedBackThankyou.aspx");
}
My table has user_id as a foreign key, I am trying to insert all the data in the SQL Server table FeedBack_T but not sure how I can accomplish this.
The data was inserted up until I added the foreign key for the user_id
sorry about the sloppy description, I am not sure how else I can explain the issue I am having.
My logic is user can leave feedback after they logged into the website, and the feedback will be stored based on the user_id.
For example, a user named Ariel logged in his user Id in the database is auto-generated based on the (seed, auto-increment). let's say his user id is 1000 and he wants to leave feedback. After he fills out the form the table should look something like this.
This is what it should look like after everything successfully uploaded
[FeedBack_Id] 1,
[firstname] Ariel,
[lastname] max,
[email] ariel#example.com,
[phone] 111-111-1111,
[subject] Something,
[feedback_type] bug report,
[comments] whatever user types,
[yesOrNo] they want to be contacted or not ,
[user_id] 1000, // User Id will be associated with the
users Table, I don't know how I can
reference this in the feedback form.
You should really use parameters in your queries - always, no exception! This will prevent SQL injection - the OWASP #1 vulnerability on the web - and it makes it a lot easier to deal with datatypes like date and others.
So your code should look something like this:
// define connection string and insert query
string CS = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string insertQuery = "INSERT INTO dbo.FeedBack_T (firstname, lastname, email, phone, subject, feedback_type, comments, yesOrNo, user_id) " +
"VALUES (#firstname, #lastname, #email, #phone, #subject, #feedback_type, #comments, #yesOrNo, #UserId);";
// create connection and command for the INSERT
using (SqlConnection con = new SqlConnection(CS))
using (SqlCommand cmdInsert = new SqlCommand(insertQuery, con))
{
// define parameters and set values
cmdInsert.Parameters.Add("#firstname", SqlDbType.NVarChar, 50).Value = txtFeedbackName.Text;
cmdInsert.Parameters.Add("#lastname", SqlDbType.NVarChar, 50).Value = txtFeedbackLastName.Text;
cmdInsert.Parameters.Add("#email", SqlDbType.NVarChar, 50).Value = txtFeedbackEmail.Text;
cmdInsert.Parameters.Add("#phone", SqlDbType.NVarChar, 50).Value = txtPhoneNumber.Text;
cmdInsert.Parameters.Add("#subject", SqlDbType.NVarChar, 50).Value = txtFeedbackSubject.Text;
cmdInsert.Parameters.Add("#feedback_type", SqlDbType.NVarChar, 50).Value = ddFeedbackType.SelectedItem.Text;
cmdInsert.Parameters.Add("#comments", SqlDbType.NVarChar, 300).Value = textAreaFeedback.Text;
cmdInsert.Parameters.Add("#yesOrNo", SqlDbType.NVarChar, 50).Value = rdbText();
// you need to somehow find / determine / pick this value on your form
cmdInsert.Parameters.Add("#UserId", SqlDbType.Int).Value = 1000;
// open connection, execute query, close connection
con.Open();
cmdInsert.ExecuteNonQuery();
con.Close();
}
if (Page.IsValid)
{
Server.Transfer("feedBackThankyou.aspx");
}
Also, I recommend to always explicitly define the columns of the target table you're inserting into - this makes your insert commands more stable and less fragile, if the underlying table changes.
Here: I don't see where you get the value for user_id from - so by not specifying that column in the INSERT INTO command, your insert will still work (it will just not insert any values for user_id, obviously).
I'm having a problem executing a SQL Server deleterecord stored procedure.
The stored procedure parameter my code is looking for is #modifiedby. I provide that but when I hit the 'actionon click' button it does nothing.
See code below
Course table:
Course_ID int Unchecked
Course_Desc varchar(500) Checked
Type_Code varchar(50) Checked
Course_Name varchar(200) Unchecked
Course_Number int Unchecked
Category_ID int Checked
Credit_Hours int Checked
Created_Date datetime Unchecked
Created_By varchar(100) Unchecked
Last_Mod_Date datetime Unchecked
Last_Mod_By varchar(100) Unchecked
Client_ID int Unchecked
Date_Deleted datetime Checked
Owner_User_ID int Checked
SubmittedByUser_ID int Checked
Stored procedure in SQL Server:
ALTER PROCEDURE [dbo].[sp_DeleteCourse]
(#CourseID AS INT,
#ModifiedBy AS VARCHAR(50),
#ReturnMsg AS VARCHAR(500) OUTPUT)
AS
--flag on the delete
SET #ReturnMsg = ''
UPDATE Dat_Courses
SET Date_Deleted = GETDATE(),
Last_Mod_By = #ModifiedBy,
Type_Code = Type_Code
WHERE Course_ID = #CourseID
DECLARE #Err AS VARCHAR(100)
BEGIN
SET #Err = ''
DELETE FROM Dat_Courses
WHERE Course_ID = #CourseID
SELECT #Err
END
VB public function to call stored procedure:
Public Function RemoveCourse(ByVal CourseID As Integer, _
ByVal ModifiedBy As String) As String
Dim courseTicket As CourseTicket
' call stored procedure
Dim conn As New SqlConnection(ConnectionString.GetComluxConnectionString())
Dim cmd As New SqlCommand(cmdText:="sp_DeleteCourse", connection:=conn)
Dim rVal As String = ""
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandTimeout = 60
cmd.Parameters.Add("#CourseID", SqlDbType.Int).Value = courseTicket.CourseID
cmd.Parameters.Add("#ModifiedBy", SqlDbType.Int).Value = courseTicket.SubmittedByUserID
cmd.Parameters.Add("#ReturnMsg", SqlDbType.VarChar, 100).Value = courseTicket.CourseName
conn.Close()
conn.Dispose()
cmd.Dispose()
conn = Nothing
cmd = Nothing
' return single row
Return rVal
End Function
Your stored procedure declaration
#ModifiedBy AS VARCHAR(50)
Your parameter
cmd.Parameters.Add("#ModifiedBy", SqlDbType.Int).Value = courseTicket.SubmittedByUserID
A varchar and an int are not compatible. Fix one or the other to match the actual column in the table. Actually, it is a little silly since you are going to delete it but I guess it might be in a log.
I am trying to concatenate the large number of id'd and to update the status of all id's.
For example:
aclid in (4604019,4604018,4604017,4604016,4604015,4604014,4604013,4604012,4604011,4604010,4604009,4604008,4604007,4604006,4604005,4604004,4604003,4604002,4604001,4604000,4603999,4603998,4603997,4603996,4603995,4603994,4603993,4603992,4603991,4603990,4603989,4603988)`
Please check my stored procedure:
ALTER PROCEDURE [dbo].[VT_ACLReportChangeStatus]
(#ChangeStatus nvarchar(50) = null,
#ACLId nvarchar(max))
AS
/* Exec VT_ACLReportChangeStatus 'Complete','4599473,4599472,4599471,4599469,4599468' */
BEGIN
UPDATE VT_ACLReport
SET Status = #ChangeStatus
WHERE ACLId IN (SELECT * FROM SplitDelimiterString(#ACLId,','))
END
Please check my code behind:
ACLId = ACLId.ToString().Trim(',');
using (SqlConnection con = new SqlConnection(cs))
{
cmd = new SqlCommand("VT_ACLReportChangeStatus", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandTimeout = 3600;
cmd.Parameters.Add(new SqlParameter("#ACLId", SqlDbType.NVarChar,-1));
cmd.Parameters.Add(new SqlParameter("#ChangeStatus", SqlDbType.NVarChar, 50));
cmd.Parameters["#ACLId"].Value = ACLId;
cmd.Parameters["#ChangeStatus"].Value = ddlChangeStatus.SelectedItem.Text.ToString();
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
AclId column data type is bigint identity.
Please can you help me in concatenating large string and to update all rows whose aclid is present.
I would suggest, create one user defined table type in sql and one class in sourecode with your respective data. You can pass object of this class to sql and in your SP you can use join between main table and this table(which is received as input parameter) to update data.
Thanks all of you for your answers.. Actually it was silly mistake,while calling splitting function in Stored procedure. In function it was varchar(8000). :) solved it.
ALTER FUNCTION [dbo].[SplitDelimiterString] (#StringWithDelimiter VARCHAR(max), #Delimiter VARCHAR(max))
RETURNS #ItemTable TABLE (Item VARCHAR(max))
AS
BEGIN
DECLARE #StartingPosition INT;
DECLARE #ItemInString VARCHAR(max);
SELECT #StartingPosition = 1;
--Return if string is null or empty
IF LEN(#StringWithDelimiter) = 0 OR #StringWithDelimiter IS NULL RETURN;
WHILE #StartingPosition > 0
BEGIN
--Get starting index of delimiter .. If string
--doesn't contain any delimiter than it will returl 0
SET #StartingPosition = CHARINDEX(#Delimiter,#StringWithDelimiter);
--Get item from string
IF #StartingPosition > 0
SET #ItemInString = SUBSTRING(#StringWithDelimiter,0,#StartingPosition)
ELSE
SET #ItemInString = #StringWithDelimiter;
--If item isn't empty than add to return table
IF( LEN(#ItemInString) > 0)
INSERT INTO #ItemTable(Item) VALUES (#ItemInString);
--Remove inserted item from string
SET #StringWithDelimiter = SUBSTRING(#StringWithDelimiter,#StartingPosition +
LEN(#Delimiter),LEN(#StringWithDelimiter) - #StartingPosition)
--Break loop if string is empty
IF LEN(#StringWithDelimiter) = 0 BREAK;
END
RETURN
END
This is my code for a stored procedure that checks for Email availability.
ALTER PROCEDURE [dbo].[usp_CheckEmailMobile](#Name VARCHAR(50), #Email NVARCHAR(50), #Password NVARCHAR(50), #CountryCode INT, #Mobile VARCHAR(50), #Result BIT OUTPUT)
AS
BEGIN
IF EXISTS (SELECT COUNT (*) FROM AUser WHERE [Email] = #Email AND [Mobile] = #Mobile)
SELECT 'FALSE'; --Email &/or Mobile does not exist in database
ELSE
--Insert the record & register the user
INSERT INTO [AUser] ([Name], [Email], [Password], [CountryCode], [Mobile]) VALUES (#Name, #Email, #Password, #CountryCode, #Mobile)
END
How do I assign the result of this SP to #Result (its the output parameter)??
here is the cs CODE: Where am I going wron in this??
protected void btnRegister_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["ConnectionString"]);
con.Open();
SqlCommand Cmd = new SqlCommand("usp_CheckEmailMobile", con);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.CommandText = "Registration";
Cmd.Parameters.AddWithValue("#Name", txtName.Text);
Cmd.Parameters.AddWithValue("#Email", txtEmailAddress.Text);
Cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
Cmd.Parameters.AddWithValue("#CountryCode", ddlCountryCode.Text);
Cmd.Parameters.AddWithValue("#Mobile", txtMobileNumber.Text);
//Cmd.Parameters.Add("#Result", DbType.Boolean);
SqlParameter sqlParam = new SqlParameter("#Result", DbType.Boolean);
//sqlParam.ParameterName = "#Result";
//sqlParam.DbType = DbType.Boolean;
sqlParam.Direction = ParameterDirection.Output;
Cmd.Parameters.Add(sqlParam);
Cmd.ExecuteNonQuery();
con.Close();
Response.Write(Cmd.Parameters["#Result"].Value);
}
went through this, dint help...
How to run the stored procedure that has OUTPUT parameter from C#?
You just set it as a normal variable like this
ALTER PROCEDURE [dbo].[usp_CheckEmailMobile](#Name VARCHAR(50), #Email NVARCHAR(50), #Password NVARCHAR(50), #CountryCode INT, #Mobile VARCHAR(50), #Result BIT OUTPUT)
AS
BEGIN
IF EXISTS (SELECT COUNT (*) FROM AUser WHERE [Email] = #Email AND [Mobile] = #Mobile)
BEGIN
SELECT 'FALSE'; --Email &/or Mobile does not exist in database
#Result = 0
END
ELSE
BEGIN
--Insert the record & register the user
INSERT INTO [AUser] ([Name], [Email], [Password], [CountryCode], [Mobile]) VALUES (#Name, #Email, #Password, #CountryCode, #Mobile)
#Result = 1
END
END
For server side code
SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["ConnectionString"]);
con.Open();
SqlCommand Cmd = new SqlCommand("usp_CheckEmailMobile", con);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.AddWithValue("#Name", txtName.Text);
Cmd.Parameters.AddWithValue("#Email", txtEmailAddress.Text);
Cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
Cmd.Parameters.AddWithValue("#CountryCode", ddlCountryCode.Text);
Cmd.Parameters.AddWithValue("#Mobile", txtMobileNumber.Text);
SqlParameter sqlParam = new SqlParameter("#Result", DbType.Boolean);
sqlParam.Direction = ParameterDirection.Output;
Cmd.Parameters.Add(sqlParam);
Cmd.ExecuteNonQuery();
con.Close();
Response.Write(Cmd.Parameters["#Result"].Value);
Do this:
ALTER PROCEDURE [dbo].[usp_CheckEmailMobile](#Name VARCHAR(50), #Email NVARCHAR(50), #Password NVARCHAR(50), #CountryCode INT, #Mobile VARCHAR(50), #Result BIT OUTPUT)
AS
BEGIN
Declare #result bit
IF EXISTS (SELECT COUNT (*) FROM AUser WHERE [Email] = #Email AND [Mobile] = #Mobile)
Begin
Set #result=0; --Email &/or Mobile does not exist in database
End
ELSE
Begin
--Insert the record & register the user
INSERT INTO [AUser] ([Name], [Email], [Password], [CountryCode], [Mobile]) VALUES (#Name, #Email, #Password, #CountryCode, #Mobile)
Set #result=1 --True
End
Select #result as Result
END
cs Code:
bool? IsSuccess= YourDBObject.usp_CheckEmailMobile(all params).FirstOrDefault().Result;
All what i am trying to do here is to set the Status field to "Complete" using stored procedure but for some reason it is not updating my table after i run the stored procedure. can someone please help me here and tell what am i doing wrong? thanks
//here is the stored proc
CREATE PROCEDURE sp_Update
#ID varchar
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if exists (select Post_ID from MyTable WHERE Post_ID = #ID)
BEGIN
UPDATE MyTable
SET Status = 'Complete'
WHERE Post_ID = #ID
END
END
//and here is the code behind
foreach (GridViewRow gr in GV_Action.Rows)
{
//string strID = gr.Cells[1].Text;
string ID = gr.Cells[1].Text;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand("sp_Update", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ID", SqlDbType.VarChar).Value = ID;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
In the code "gr.Cells[1].Text" Cells[x] is zero based. If the ID is in the very first column then you need 'gr.Cells[0].Text'. Put a breakpoint on the very next line and see what value you have there.