I have some code that inserts and updates data into a sql table. I use ExecuteScalar to check if a row already exists with the same UserName and DeviceId. If it exists, we run the update stored procedure, overriding the DataSource, PendingCount and LastUpdated fields. If the row doesn't exist, we use the insert stored procedure. The insert stored procedure works great, but the update stored procedure doesn't seem to do anything. The row remains the same. Here is the code in question:
try
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlCommand comm = new SqlCommand(query, sqlConnection))
{
comm.CommandType = System.Data.CommandType.Text;
comm.Parameters.Add(new SqlParameter("#DataSource", pending.DataSource));
comm.Parameters.Add(new SqlParameter("#LastUpdated", pending.LastUpdated));
comm.Parameters.Add(new SqlParameter("#PendingCount", pending.PendingCount));
comm.Parameters.Add(new SqlParameter("#DeviceId", pending.DeviceId));
comm.Parameters.Add(new SqlParameter("#UserName", pending.UserName));
int rowCount = (int)comm.ExecuteScalar();
if (rowCount > 0)
{
using (SqlCommand sqlComm = new SqlCommand("sp_UpdatePendingAttachments", sqlConnection))
{
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.Parameters.Add(new SqlParameter("#DataSource", pending.DataSource));
sqlComm.Parameters.Add(new SqlParameter("#LastUpdated", pending.LastUpdated));
sqlComm.Parameters.Add(new SqlParameter("#PendingCount", pending.PendingCount));
sqlComm.Parameters.Add(new SqlParameter("#DeviceId", pending.DeviceId));
sqlComm.Parameters.Add(new SqlParameter("#UserName", pending.UserName));
}
}
else
{
using (SqlCommand sqlCommand = new SqlCommand("sp_InsertPendingAttachments", sqlConnection))
{
sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
sqlCommand.Parameters.Add(new SqlParameter("#DataSource", pending.DataSource));
sqlCommand.Parameters.Add(new SqlParameter("#UserName", pending.UserName));
sqlCommand.Parameters.Add(new SqlParameter("#DeviceId", pending.DeviceId));
sqlCommand.Parameters.Add(new SqlParameter("#PendingCount", pending.PendingCount));
sqlCommand.Parameters.Add(new SqlParameter("#LastUpdated", pending.LastUpdated));
sqlCommand.ExecuteNonQuery();
}
}
}
}
return new BaseResponse();
}
The stored procedure for updating is "sp_UpdateStoredProcedure":
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_UpdatePendingAttachments]
(
-- Add the parameters for the stored procedure here
#DataSource VARCHAR(150) = '',
#DeviceId VARCHAR(150) = '',
#UserName VARCHAR(150) = '',
#PendingCount int = null,
#LastUpdated DateTime = null
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Insert statements for procedure here
UPDATE PendingAttachments
SET DataSource = #DataSource, PendingItemsCount = #PendingCount, LastUpdated = #LastUpdated
WHERE DeviceId = #DeviceId AND UserName = #UserName
END
GO
Any idea why updating rows isn't working? Is it a problem with the stored procedure, or the c# code? Any feedback is appreciated!
You need to use some execution method on the mentioned place in the attached image to execute your Transact-SQL statement.
You have used ExecuteScaler() once to figure out the existing record but at the time of updation you have missed adding any execution method.
Related
I have this stored procedure:
create procedure sp_findMaxEmployee
#maxID as varchar(10) OUTPUT
as
SET #maxID = (SELECT MAX(e_ID) FROM Employee)
go
I try to register an output parameter like this:
public string generateID()
{
connection = new SqlConnection(connectionStr);
cmd = new SqlCommand("sp_findMaxEmployee", connection);
SqlParameter param = new SqlParameter();
param.ParameterName = "#maxID";
param.Direction = ParameterDirection.Output;
param.SqlDbType = SqlDbType.VarChar;
cmd.Parameters.Add(param);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
return cmd.Parameters["#maxID"].Value.ToString();
}
I tried to execute this procedure in SQL and it return right value, but when I execute project in debug mode, it shows me error:
String[0]: the Size property has an invalid size of 0.
Null value? Can you help me, thank you so much!
Assuming e_ID is a integer, you can just perform a SELECT and ExecuteScalar to return a single value:
create procedure sp_findMaxEmployee
as
SELECT MAX(e_ID) FROM Employee
go
Then in code, something like:
public string generateID()
{
connection = new SqlConnection(connectionStr);
cmd = new SqlCommand("sp_findMaxEmployee", connection);
connection.Open();
var maxId = cmd.ExecuteScalar();
connection.Close();
return maxId.ToString();
}
Finally, there's probably a deeper question as to why you are returning the last ID, hopefully it's not to get the next available ID, which you should let SQL do on your behalf by letting it auto-increment.
Little Tweak for SP
The Tweak is not necessary but it looks better this way :) and also please avoid using sp_ prefix for your stored procedures. Use usp_ instead.
create procedure usp_findMaxEmployee
#maxID as varchar(10) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #maxID = MAX(e_ID) FROM Employee;
END
Calling from Code
public string generateID()
{
SqlConnection conn = new SqlConnection(connectionStr);
SqlCommand cmd = new SqlCommand("usp_findMaxEmployee", conn);
cmd.CommandType = CommandType.StoredProcedure;
// set up the parameters
cmd.Parameters.Add("#maxID", SqlDbType.VarChar, 10).Direction = ParameterDirection.Output;
// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();
// read output value from #maxID
String maxID = Convert.ToString(cmd.Parameters["#maxID"].Value);
conn.Close();
return maxID;
}
Note
Use the using block of Try/Catch/Finnaly blocks to close connection if anything goes wrong.
You need to specify a .Size for your parameter. Your stored procedure specifies an output of varchar(10), so you should set the param.Size = 10;
You need to specify that cmd.CommandType = CommandType.StoredProcedure, the default CommandType is CommandType.Text
Make those changes and your method works as you intended.
using this coding,while i give fruitId ,i need to retrieve fruitname,using this it shows some error..any one help...
string constring = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
using (SqlConnection con = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand("savefruit11", con))
{
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#FruitsId", int.Parse(TextBox3.Text.Trim()));
cmd.Parameters.Add("#Fruitsname", SqlDbType.VarChar, 50);
cmd.Parameters["#Fruitsname"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
con.Close();
TextBox4.Text = "Fruit Name:"+cmd.Parameters["#FruitName"].Value.ToString();
}
}
Store procedure for the above code.
use[FruitsDB]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[savefruit11]
#FruitId INT,
#FruitName VARCHAR(50) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #FruitName = Fruitsname
FROM Fruits1
WHERE FruitsId = #FruitId
END
cmd.Parameters.Add("#Fruitsname", SqlDbType.VarChar, 50);
cmd.Parameters["#Fruitsname"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
con.Close();
TextBox4.Text = "Fruit Name:"+cmd.Parameters["#FruitName"].Value.ToString();
Your parameter is called #Fruitsname, but you get it back with #FruitName. You have an additional s in the first version. Make them consistent by changing the first #FruitsName to #FruitName which will match what you have in the stored procedure.
Or, as Henk suggested in the comments create a const string to contain your parameter name so that it is consistent across all usages.
Use cmd.ExecuteQuery or cmd.ExecuteScalar
//To Execute SELECT Statement
ExecuteQuery()
//To Execute Other Than Select Statement(means to Execute INSERT/UPDATE/DELETE)
ExecuteNonQuery()
with your udpate
s is missing in parameter name in stored procedure
Use the following example way
using (SqlConnection connection = new SqlConnection())
{
string connectionStringName = this.DataWorkspace.AdventureWorksData.Details.Name;
connection.ConnectionString =
ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
string procedure = "HumanResources.uspUpdateEmployeePersonalInfo";
using (SqlCommand command = new SqlCommand(procedure, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(
new SqlParameter("#EmployeeID", entity.EmployeeID));
command.Parameters.Add(
new SqlParameter("#NationalIDNumber", entity.NationalIDNumber));
command.Parameters.Add(
new SqlParameter("#BirthDate", entity.BirthDate));
command.Parameters.Add(
new SqlParameter("#MaritalStatus", entity.MaritalStatus));
command.Parameters.Add(
new SqlParameter("#Gender", entity.Gender));
connection.Open();
command.ExecuteNonQuery();
}
}
reference from MSDN
http://msdn.microsoft.com/en-us/library/jj635144.aspx
I am inserting rows in sql table through my c# code , which calls a Stored procedure .
C# code:
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
while (myfederationReader.Read())
{
myCommand.Parameters["#bid"].Value = myfederationReader["BusinessId"];
myCommand.Parameters["#uid"].Value = myfederationReader["UId"];
myCommand.Parameters["#imp"].Value = myfederationReader["Impression"];
myCommand.Parameters["#ctr"].Value = myfederationReader["CTR"];
rowsAffected = myCommand.ExecuteNonQuery();
}
Stored proc:
CREATE PROCEDURE [dbo].[FederationUpdateCTRAndImpressionCountsForAllYPIds]
#bid uniqueidentifier,
#uid uniqueidentifier,
#imp varchar(255),
#ctr varchar(255)
AS BEGIN
UPDATE BasicBusinessInformation
SET BasicBusinessInformation.CTR = #ctr , BasicBusinessInformation.Impression = #imp
WHERE BasicBusinessInformation.BusinessId = #bid AND BasicBusinessInformation.UId = #uid
END
On executing it , following error is reported:
procedure has no parameters and arguments were supplied
Try clearing the Command parametres
[C#]
public bool ExportAndClear() {
SqlParameter[] myParamArray = new SqlParameter[myCmd.Parameters.Count - 1];
myCmd.Parameters.CopyTo(myParamArray, 0);
myCmd.Parameters.Clear();
return true;
}
try to fetch data from reader before you fire this command
like
1)Fetch data from reader and store in list or datatable
2)For loop on list or datatable
3)in for loop fire this command
Try moving the following
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
In the while loop, see if you get different results.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
returning int value from stored procedure and check it in asp.net code to validate login form
hello all please i need help in this code as it is stored procedure validate username and password , the problem here is that form validate any data even it doesn't stored in database and i tried to fix code many times but really i haven't any more thing to do in it , any one can help me to solve this problem
this is stored procedure
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[login_procedure] #username Varchar =50, #password varchar=50, #result int OUTPUT
as
Declare #user_name varchar , #pass_word varchar
Set #user_name = #username
Set #pass_word = #password
if EXISTS (select #username , #password from data where username= #user_name and password=#pass_word)
select #result=1
else
select #result=0
and this is asp.net code
SqlConnection conn = new SqlConnection ("Data Source=ANAGUIB-LAPNEW\\SQLEXPRESS;Initial Catalog=account;Integrated Security=True");
SqlCommand cmd = new SqlCommand("login_procedure", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paramReturnValue = new SqlParameter();
paramReturnValue.ParameterName = "#result";
paramReturnValue.SqlDbType = SqlDbType.Int;
cmd.Parameters.Add(paramReturnValue);
cmd.Parameters["#result"].Direction = ParameterDirection.Output;
conn.Open();
cmd.Parameters.AddWithValue("#username", TextBox1.Text);
cmd.Parameters.AddWithValue("#password", TextBox2.Text);
int resultID = Convert.ToInt32(cmd.ExecuteScalar());
if (Convert.ToInt32(resultID) == 0)
{
Response.Redirect("hello.aspx");
}
else
{
Response.Write("error");
}
conn.Close();
}
Your stored-procedure has OUTPUT parameter and it is good practice to access value of output parameter after closing the connection.
I've changed proc.
ALTER PROCEDURE login_procedure
#username Varchar(50),
#password varchar(50),
#result int OUTPUT
AS
IF EXISTS (select username from data where username= #username and password=#password)
set #result=1
else
set #result=0
Demo: How to pass parameters (IN and OUT)?
SqlConnection cn = new SqlConnection(cnstr);
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandText = "login_procedure";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter param1 = new SqlParameter("#username", System.Data.SqlDbType.VarChar, 50);
SqlParameter param2 = new SqlParameter("#password", System.Data.SqlDbType.VarChar, 50);
SqlParameter resultParam= new SqlParameter("#result", System.Data.SqlDbType.Int);
resultParam.Direction = System.Data.ParameterDirection.Output;
param1.Value = TextBox1.Text;
param2.Value = TextBox2.Text;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
cmd.Parameters.Add(resultParam);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
int retVal;
int.TryParse(resultParam.Value.ToString(),out retVal);
if(retVal==1)
//
else
//
In this code
if EXISTS (select #username ,
#password
from data
where username= #user_name and password=#pass_word)
select #result=1
else
select #result=0
You are returning 1 if the given input is validated in your C# code you are giving error when the return value is not 0, that is why every input even which does not exist in your table is validated.Try this;
if (resultID == 1)
{
Response.Redirect("hello.aspx");
}
else
{
Response.Write("error");
}
And you do not have to Convert the return value of stored procedure twice, once is enough.
I have a stored procedure, which returns the unique identifier after insertion ##identity. I tried it in the server explorer and it works as expected #RETURN_VALUE = [identifier].
In my code I added a parameter called #RETURN_VALUE, with ReturnValue direction first, than any other parameters, but when I run my query with ExecuteNonQuery() that parameter remains empty. I don't know what I've done wrong.
Stored Procedure
ALTER PROCEDURE dbo.SetAuction
(
#auctionID int,
#itemID int,
#auctionType tinyint,
#reservationPrice int,
#maxPrice int,
#auctionEnd datetime,
#auctionStart datetime,
#auctionTTL tinyint,
#itemName nchar(50),
#itemDescription nvarchar(MAX),
#categoryID tinyint,
#categoryName nchar(50)
) AS
IF #auctionID <> 0
BEGIN
BEGIN TRAN T1
UPDATE Auction
SET AuctionType = #auctionType,
ReservationPrice = #reservationPrice,
MaxPrice = #maxPrice,
AuctionEnd = #auctionEnd,
AuctionStart = #auctionStart,
AuctionTTL = #auctionTTL
WHERE AuctionID = #auctionID;
UPDATE Item
SET
ItemName = #itemName,
ItemDescription = #itemDescription
WHERE
ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = #auctionID);
COMMIT TRAN T1
RETURN #auctionID
END
ELSE
BEGIN
BEGIN TRAN T1
INSERT INTO Item(ItemName, ItemDescription, CategoryID)
VALUES(#itemName, #itemDescription, #categoryID);
INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL)
VALUES(##IDENTITY,#auctionType,#reservationPrice,#maxPrice,#auctionEnd,#auctionStart,#auctionTTL);
COMMIT TRAN T1
RETURN ##IDENTITY
END
C# Code
cmd.CommandText = cmdText;
SqlParameter retval = new SqlParameter("#RETURN_VALUE", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
cmd.Parameters.AddRange(parameters);
cmd.Connection = connection;
connection.Open();
cmd.ExecuteNonQuery();
return (int)cmd.Parameters["#RETURN_VALUE"].Value;
Just tried on my box and this works for me:
In SQL Server:
DROP PROCEDURE TestProc;
GO
CREATE PROCEDURE TestProc
AS
RETURN 123;
GO
In C#
string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;";
using (SqlConnection cn = new SqlConnection(cnStr)) {
cn.Open();
using (SqlCommand cmd = new SqlCommand("TestProc", cn)) {
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter returnValue = new SqlParameter();
returnValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(returnValue);
cmd.ExecuteNonQuery();
Assert.AreEqual(123, (int)returnValue.Value);
}
}
I solved the problem:
you have to set SqlCommand.CommandType to CommandType.StoredProcedure in order to get return values and/or output parameters. I haven't found any documentation about that, but now everything works.
Do you get the value of you EXEC in TSQL? I wonder if refactoring the TSQL would help (and using SCOPE_IDENTITY():
so change:
COMMIT TRAN T1
RETURN ##IDENTITY
to:
SET #auctionID = SCOPE_IDENTITY()
COMMIT TRAN T1
RETURN #auctionID
(I would also change the other ##IDENTITY to SCOPE_IDENTITY())
As a minor optimisation, you could also use:
return (int)retval.Value;
but this side of things should have worked "as is" from what I can see (hence why I'm focusing on the TSQL).
Some one can also use this simple and short method to calculate return value from SP
In SQL:
Create Table TestTable
(
Int Id
)
CREATE PROCEDURE Proc_TestProc
#Id
AS
Begin
Set NOCOUNT ON //Use this line if you don't want to return any message from SQL
Delete from TestTable where Id = #Id
return 1
Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property
End
Sql Server always returns Int type value only.
and in C#
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString()))
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Id", 1);
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
You can also check your return value in SQL by using this command:
DECLARE #return_status int;
EXEC #return_status = dbo.[Proc_TestProc] 1;
SELECT 'Return Status' = #return_status;
print 'Returned value from Procedure: ' + Convert(varchar, #return_status); // Either previous or this line both will show you the value of returned value
you can use standart ways that you use before in normal queries but in Sql command you must write EXEC before your store procedure name and dont use commandtype like this :
SqlConnection con = new SqlConnection(["ConnectionString"])
SqlCommand com = new SqlCommand("EXEC _Proc #id",con);
com.Parameters.AddWithValue("#id",["IDVALUE"]);
con.Open();
SqlDataReader rdr = com.ExecuteReader();
ArrayList liste = new ArrayList();
While(rdr.Read())
{
liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) ..
}
con.Close();