Inserting data into SQL Server by using a stored procedure - c#

I have a problem while inserting records into SQL Server.
The string from C# doesn't show up in SQL Server as I'm inserting the sql just insert the first char
Example: If I insert 22222 in the data base just the first 2 inserted
Note I'm using a stored procedure for my first time.
This is my code:
public void insert_workshop(DateTime Pdate, string PTime, string PDesc, byte[] Img)
{
SqlCommand cmd = new SqlCommand("[InsertWorkShops]", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#WorkshopsDate", SqlDbType.Date).Value = Pdate;
cmd.Parameters.Add("#Time", SqlDbType.NVarChar).Value = PTime;
cmd.Parameters.Add("#WorkshopsDescription", SqlDbType.NVarChar).Value = PDesc;
cmd.Parameters.Add("#WorkshopsImage", SqlDbType.Image).Value = Img;
cmd.Parameters.Add("#CreatedBy", SqlDbType.NVarChar).Value = 1;
try
{
cmd.ExecuteNonQuery();
Msg = "Add Done ";
}
catch
{
Msg = "Error While Adding";
}
WorkShopTransactions Ws = new WorkShopTransactions();
Ws.insert_workshop(WorkShopDT.Value, txtWorshopTime.Text.ToString(),
txtWorkshopDescriptions.Text.ToString(), img);
T-SQL:
ALTER PROCEDURE [dbo].[InsertWorkShops]
#WorkshopsDate date,
#Time nvarchar,
#WorkshopsDescription nvarchar,
#WorkshopsImage image,
#CreatedBy int
AS
BEGIN
SET NOCOUNT ON;
insert into Workshops
values(#WorkshopsDate, #Time, #WorkshopsDescription, #WorkshopsImage, #CreatedBy)
END

In the stored procedure, you have declared your nvarchar parameters without a length. They default to nvarchar(1).

Related

Stored procedure causing transaction error while executing from C# application

I have the following stored procedure written in SQL database. It executes 2 procedures in different databases. The inner procedures are simple update and insert queries without any explicit TRANSACTION statement applied.
ALTER PROCEDURE [dbo].[usp_1]
#UserID nvarchar(MAX),
#report nvarchar(max),
#sqlErrorMsg nvarchar(MAX) OUTPUT
AS
BEGIN
EXEC #ret = [db1].[dbo].[usp_2]
#user = #UserID,
#msg = #sqlErrorMsg OUTPUT,
#date = #reportDate
set #sqlErrorMsg = 'Report update Status: ' + #sqlErrorMsg
EXEC #ret = [db2].[dbo].[usp_3]
#UserID = #UserID,
#msg = #sqlErrorMsg OUTPUT,
#date = #reportDate
END
This procedure runs perfectly when I execute it in SQL Management studio. But when I run it using a C# code that calls this procedure, I get the following error:
The current transaction cannot be committed and cannot support
operations that write to the log file. Roll back the transaction. The
current transaction cannot be committed and cannot support operations
that write to the log file. Roll back the transaction.
C# Code: (Conn is defined outside with proper connection string and is tested)
public int Upload_Excel_Timer(string userID, string report, out string message)
{
int ret;
SqlCommand cmd = new SqlCommand("usp_1", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#UserID", userID);
cmd.Parameters.AddWithValue("#report", report);
SqlParameter outputParameter = cmd.Parameters.Add("#sqlErrorMsg", SqlDbType.NVarChar, 255);
outputParameter.Direction = ParameterDirection.Output;
SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
try
{
if (conn.State.Equals(ConnectionState.Closed))
conn.Open();
int tempval = cmd.ExecuteNonQuery();
ret = Convert.ToInt32(returnParameter.Value);
message = outputParameter.Value.ToString();
}
catch (Exception e)
{
ret = -1;
message = e.Message;
}
finally
{
conn.Close();
}
return ret;
}

MySQL. insert into stored procedure affected rows' count is always 0

I call a stored procedure from my c# code to insert a row into a table. My problem is that i always get 0 affected rows. Here are the codes
Stored procedure code
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `AddInfo`(
IN _activationDate datetime,
IN _organization varchar(100),
IN _email varchar(45),
IN _tableName varchar(35))
BEGIN
set #sqlquery = concat('insert into ', _tableName, ' values (?, ?, ?)');
prepare stmt from #sqlquery;
set #activationDate = _activationDate;
set #orgaization = _organization;
set #email = _email;
execute stmt using #activationDate, #orgaization, #email,;
deallocate prepare stmt;
END
C# code
using (MySqlConnection conn = new MySqlConnection(connStr))
{
string spName = "AddInfo";
MySqlCommand cmd = new MySqlCommand(spName, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#_activationDate", activationDate);
cmd.Parameters.AddWithValue("#_organization", organization);
cmd.Parameters.AddWithValue("#_email", email);
cmd.Parameters.AddWithValue("#_tableName", tableName);
conn.Open();
int rowsAffected = cmd.ExecuteNonQuery();
bool added = rowsAffected == 1 ? true : false;
conn.Close();
return added;
}
when i run this code the row is successfully added to the table, but rowsAffected is always 0. Where is my problem? Thank you

Getting stored procedures multiple result

I have a stored procedure which returns new ids.
create proc [dbo].[WriteIT]
(#deg nvarchar(max))
as
DECLARE #s nvarchar(max)
set #s = 'INSERT INTO test OUTPUT inserted.ID VALUES '
set #s += #deg
exec (#s)
How can I get that multiple results of stored procedures into a int[]?
string con = "Server=.;Database=Adb;Trusted_Connection=True";
SqlConnection connet = new SqlConnection(con);
SqlCommand cm = new SqlCommand("WriteIT", connet);
cm.CommandType = System.Data.CommandType.StoredProcedure;
bd = new StringBuilder();
string veri = "({0}),";
string sablon = "'{0}','{1}'";
for (int i = 0; i < 50; i++)
{
bd.Append(string.Format(veri, string.Format(sablon, new Random().Next(0, 100000).ToString(), new Random().Next(0, 100000).ToString())));
}
cm.Parameters.AddWithValue("#deger", bd.ToString().Substring(0, bd.Length - 1));
if (connet.State == System.Data.ConnectionState.Closed)
connet.Open();
string a = cm.ExecuteScalar();
ExecuteScalar is meant to return only the first column of the first row from the result..
If your SProc would return more than one value, you could use the ExecureReader() method.
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "StoredProcedureName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
sqlConnection1.Close();
You should also read on Random class. You should use the same instance to generate numbers.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Usp_CRMEntryInsert]
#custnam nvarchar(250),
#proj nvarchar(255),
#projid int,
#contact nvarchar(100),
#updfile nvarchar(150),
#vtype nvarchar(100),
#sts varchar(15),
#recsts varchar(1),
#entryid int,
#entrydate datetime,
#dataentrydate datetime
AS
BEGIN
SET NOCOUNT ON;
insert into CRMEntry (custnam,Proj,projid,contact,updfile,vtype,status,rec_status,entered_id,entered_date,entry_date) values (#custnam,#proj,#projid,#contact,#updfile,#vtype,#sts,#recsts,#entryid,#entrydate,#dataentrydate)
select scope_identity()
This Scope_identity() return max value
maxid = cmd.ExecuteScalar()

how to pass ref variable to a SQL stored Procedure using ADO.NET?

i have that code using LINQ to call a stored procedure to save some data into database then return two variables from the stored procedure.
[ASP.NET code]
dbDataContext dbo = new dbDataContext();
dbo.AddNewDoctor(doctorName, email, password, ref DocId, ref result);
[SQL]
create PROCEDURE [dbo].[AddNewDoctor]
#doctorname nvarchar(100),
#email nvarchar(100),
#password nvarchar(MAX),
#docId int out,
#Result int out
AS
BEGIN
SET NOCOUNT ON;
declare #idCounter int
select #idCounter = count(*) from dbo.doctors
if EXISTS (select * from dbo.doctors where e_mail = #email)
begin
SET #Result = -1
set #docId= 0
end
else
begin
INSERT INTO [dbo].[doctors]
([doctor_id]
,[doctorname]
,[e_mail]
,[password]
VALUES
((#idCounter +1)
,#docotorname
,#email
,#password
)
SET #Result = 1
set #docId= (#idCounter + 1)
end
END
this code work very well what i want to do now to use ADO instead of LINQ, the problem with me is that i can't pass the ref variable as in LINQ so how can i do it using ADO
You'll have to do something like this. Use ParameterDirection
SqlParameter output = new SqlParameter(paramName, dbType);
output.Direction = ParameterDirection.Output;
command.Parameters.Add(output);
In your case you've to use SqlDbType.Int. Use Value property to read return value.
SqlParameter output = new SqlParameter(paramName, SqlDbType.Int);
output.Direction = ParameterDirection.Output;
command.Parameters.Add(output);
int Result = (int) output.Value; or int? Result = (int?) output.Value;
Try this
using (SqlConnection con = new SqlConnection("Your connection string"))
{
con.Open();
SqlCommand mycommand = new SqlCommand();
mycommand.Connection = con;
mycommand.CommandText = "dbo.AddNewDoctor";
mycommand.CommandType = CommandType.StoredProcedure;
mycommand.Parameters.AddWithValue(doctorName);
mycommand.Parameters.AddWithValue(email);
mycommand.Parameters.AddWithValue(password);
mycommand.Parameters.AddWithValue(ref DocId);
mycommand.Parameters.AddWithValue(ref result);
mycommand.ExecuteNonQuery();
}
Hope this helps thanks.
Refer to this article, there is an working example:
http://csharp-guide.blogspot.de/2012/05/linq-to-sql-call-stored-procedure-with_25.html

How to modify Stored Procedure or ASP.net Code to get autogenerated Id after inserting new row

I m creating new user registration moduleand for that i wrote following stored proc.
PROCEDURE [dbo].[addNewUser]
-- Add the parameters for the stored procedure here
#usertype VarChar(10),
#useremail VarChar(70),
#userpass VarChar(20),
#fullname VarChar(70),
#city VarChar(70),
#state Int,
#allowAlerts Bit,
#allowLetter Bit,
#aboutMe NVARCHAR(160)
As
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if ((select count(user_info._id) from user_info where useremail like #useremail) = 0)
BEGIN
Insert Into user_info
(usertype,useremail,userpass,fullname,city,[state],allowAlerts,allowLetters,aboutMe)
Values
(
#usertype,
#useremail,
#userpass ,
#fullname,
#city,
#state,
#allowAlerts,
#allowLetter,
#aboutMe
)
Select ##IDENTITY as NewID
END
Else
BEGIN
Print '-1'
END
And following is the simple ASP.net C# Code that I try to use
public int registerNewUser(string usertype, string useremail, string userpass, string fullname, string city, string state, string allowAlerts, string allowLetter, string aboutMe)
{
con = new SqlConnection(connectionString);
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "addBlogEntry";
cmd.Parameters.Add("#usertype", SqlDbType.VarChar).Value = usertype;
cmd.Parameters.Add("#useremail", SqlDbType.VarChar).Value = useremail;
cmd.Parameters.Add("#userpass", SqlDbType.VarChar).Value = userpass;
cmd.Parameters.Add("#fullname", SqlDbType.VarChar).Value = fullname;
cmd.Parameters.Add("#city", SqlDbType.VarChar).Value = city;
cmd.Parameters.Add("#state", SqlDbType.VarChar).Value = Convert.ToInt16(state);
cmd.Parameters.Add("#allowAlerts", SqlDbType.VarChar).Value = Convert.ToInt16(allowAlerts);
cmd.Parameters.Add("#allowLetter", SqlDbType.VarChar).Value = Convert.ToInt16(allowLetter);
cmd.Parameters.Add("#aboutMe", SqlDbType.VarChar).Value = aboutMe;
try
{
if (con.State != ConnectionState.Open)
con.Open();
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
// some code to be written here so that i can return userID(success) or -1(if that username is already registered)
return 0;
}
catch (Exception Ex)
{
con.Close();
con.Dispose();
return 0;
}
}
Through my C# code i want to return either auto generated userId which my stored procedures returns to me or if user alrady exists than i want to return -1
Please tell how to do this?
Thanks in advance :)
Yes, you can use ExecuteScalar() and change
Print '-1'
into
Select -1 as NewID
First of all, you should use SELECT SCOPE_IDENTITY() inside your stored proc to retrieve the new ID value (##IDENTITY can return false results).
And yes, if you want to get the result back, you need to call either .ExecuteScalar() or .ExecuteReader() and then read that value back.
And while you're at it - I'd also recommend putting your SqlConnection and SqlCommand objects into using blocks - so instead of your code, use this:
using(con = new SqlConnection(connectionString))
using(cmd = new SqlCommand(con))
{
..... // put the rest of your code here
}
If you want to create an output parameter for your stored proc, and set it to the new key you can access it that way. ExecuteNonQuery will return the number of rows affected, so that can be used as well. Something like this:
cmd.Parameters.Add("#uniquID", SqlDbType.Int).Direction = ParameterDirection.Output;
// Your other code...
var result = cmd.ExecuteNonQuery();
// Your other code...
return (result == 1) ? (int)cmd.Parameters["#uniquID"].Value : -1;

Categories

Resources