Inserting with an Auto-Incrementing ID - c#

I am inserting into a database using a stored procedure and i am getting the error:
Procedure or function 'sp_Addrecord' expects parameter '#RecordNumber', which was not supplied.
RecordNumber is an auto incrementing ID so i understand id have to omit it from my insert command and specify which columns and where i have to insert to avoid this but i am calling the procedure which is handled by another class so where would i be able to specify this as you would normally say something like this:
SqlCommand cmd = new SqlCommand("INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)", conDatabase);
Here is my code, i avoided the using statement for simplicity of this example:
List<CarRecord> carRecords;
private void Save_Record_Click(object sender, RoutedEventArgs e)
{
SqlConnection conDatabase = new SqlConnection(String.Format(#"Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}", SQLFunctions.connectSQL.SQLSERVER_ID, SQLFunctions.connectSQL.SQLDatabaseName, SQLFunctions.connectSQL.SQLServerLoginName, SQLFunctions.connectSQL.SQLServerPassword));
conDatabase.Open();
SqlCommand cmd = new SqlCommand("sp_Addrecord", conDatabase);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();
}
public bool Addrecord(CarRecord DataRecord)
{
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
}
EDIT - Stored Procedure:
USE [SDC Logging]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_Addrecord]
#RecordNumber int,
#Date nvarchar(50),
#Time nvarchar(50),
AS
BEGIN
SET NOCOUNT ON;
WITH [source](RecordNumber, Date, Time)
AS
(
SELECT #RecordNumber, #Date, #Time,
)
MERGE dbo.Bags AS [target] USING [source]
ON [target].Date = [source].Date
WHEN MATCHED THEN UPDATE SET
[target].Date = #Date,
[target].Time = #Time,
WHEN NOT MATCHED THEN
INSERT ( Date, Time, )
VALUES( #Date, #Time, );
SELECT SCOPE_IDENTITY()
END

The error says it all. Your sp_Addrecord has a parameter specified that you are supplying. Basically, the parameters you specify here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
must match the name and datatype of the parameters defined by sp_Addrecord stored procedure. In addition, make sure your stored procedure's query matches this query...
INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)
Edit based on your Edit
You need to specified the #RecordNumber parameter here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#RecordNumber", SqlDbType.Int, DataRecord.recordNumber),
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
Don't worry about the insert just make sure that when inserting you pass a "invalid record number" such as -1, if the MERGE statement doesn't find the record with id of -1 it will successfully insert the record with an auto-generated Id with the help of your identity column

Try This.
You don't need to call separate method Addrecord.
However, you still want to use a separate method. Add code below in the AddRecord method and remove existing code:
SqlParameter []parms = new SqlParameter[1];
parms[0] = new SqlParameter("#Date",DataRecord.carDate) ;
parms[1] = new SqlParameter("#Time",DataRecord.carTime) ;
cmd.Parameters.AddRange(parms);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();

Related

how to get an auto incrementing stored procedure in mysql

I'm running the below code to call p_CreateRequest. All i want is to get the ID Back but i get an Field "ID" Does not have a default value error. HELP
using (var conn = Conn)
{
using (var cmd = new MySql.Data.MySqlClient.MySqlCommand("p_CreateRequest", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter("CREATED_DATE", cREATED_DATE));
cmd.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter("WORKFLOW_ID", wORKFLOW_ID));
cmd.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter("CREATED_BY_USER_ID", cREATED_BY_USER_ID));
cmd.Parameters.Add(new MySql.Data.MySqlClient.MySqlParameter("ID", iD));
cmd.Parameters["ID"].Direction = System.Data.ParameterDirection.Output;
cmd.ExecuteNonQuery();
iD = (int)cmd.Parameters["ID"].Value;
return iD;
}
}
the sprocs code is
CREATE DEFINER="finnsch"#"%" PROCEDURE "p_CreateRequest"(CREATED_DATE datetime,
WORKFLOW_ID int, CREATED_BY_USER_ID varchar(50),INOUT ID int)
BEGIN
DECLARE LASTCHANGEDATE Date;
SET LASTCHANGEDATE = Now();
INSERT INTO REQUEST
(CREATED_DATE,WORKFLOW_ID,CREATED_BY_USER_ID,
CURRENT_STEP_ID,LAST_ACTION_BY,LAST_EDIT_DATE)
select
CREATED_DATE,WORKFLOW_ID,CREATED_BY_USER_ID,s.ID,
CREATED_BY_USER_ID,LASTCHANGEDATE
from
STEP s where s.WORKFLOW_ID=WORKFLOW_ID and s.IS_INITIAL=1;
set ID = Last_Insert_ID();
END
Need to change the table and set ID to:
id int(20) NOT NULL AUTO_INCREMENT,
Also, check if MySql is in Strict SQL Mode. If it is, then need to run the query:
SET GLOBAL sql_mode=''.
You can also modify your my.cnf / my.ini to ensure you aren't setting STRICT_ALL_TABLES and/or STRICT_TRANS_TABLES. See this for more information:
Field 'id' doesn't have a default value?

Parameter not passed from program to stored procedure

I am passing the parameter like in C# page,
conn.Open();
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.CommandText = commandtype.storedprocedure;
cmd.Parameters.AddWithValue("?user", user)
cmd.Parameters.AddWithValue("?name", name);
On the mysql stored procedures used 2 parameter for record exists finds
#id integer,
#name varchar(200)
BEGIN
IF EXISTS (SELECT * FROM usertable WHERE id = #id and mode =0 limit 1 )
THEN
UPDATE usertable SET name = name where id=#id and mode = 0;
ELSE
INSERT INTO usertable (name, mode)VALUES (#name`enter code here`,0);
END IF;
END
Another way of sending variables to a stored proc that I've used with no problem:
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#name", SqlDbTpye.Varchar).Value = name;
I think you can specify variable by size and type like this:
SqlDbTpye.Varchar,200
But not able to test that right now.
You need to make sure the prefixes for the parameters match. If you use "#" in your stored procedure, you need to use "#" in C#, too, not "?".
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#user", user)
cmd.Parameters.AddWithValue("#name", name);

SQL SERVER 2005 return value

Hi all I have the following stored procedure
#UserName varchar(150),
#UserEmail varchar(300),
#UserPassword varchar(150),
#ContactNumber varchar(150),
#ContactMobile varchar(150),
#AreaOfCountry varchar(150),
#UserId int OUTPUT,
#AllreadyReg int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--DECLARE #UserId int, #AllreadyReg int
IF (SELECT COUNT(UserId) FROM Users WHERE (UserName = #UserName) OR (UserEmail = #UserEmail)) > 0
BEGIN
SET #UserId = 0
SET #AllreadyReg = 1
END
ELSE
BEGIN
INSERT INTO Users (UserName,UserEmail,UserPassword,ContactNumber,ContactMobile,AreaOfCountry) VALUES (#UserName,#UserEmail,#UserPassword,#ContactNumber,#ContactMobile,#AreaOfCountry)
SELECT #UserId = SCOPE_IDENTITY()
SET #AllreadyReg = 0
END
however when I use it using c# and asp.net its not returning anything, however when I just execute it it does have a results #UserId and #AllreadyReg but the return value is 0 and a single field.
my c# code is below but it never has any rows
using (SqlConnection con = new SqlConnection(connectionString))
{
Response.Write("Line 61");
using (SqlCommand cmd = new SqlCommand("spR_Register", con))
{
Response.Write("line 64");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#UserName", TxtUsername.Text.Trim());
cmd.Parameters.AddWithValue("#UserEmail", TxtEmail.Text.Trim());
cmd.Parameters.AddWithValue("#UserPassword", TxtPassword.Text.Trim());
cmd.Parameters.AddWithValue("#ContactNumber", TxtPhone.Text);
cmd.Parameters.AddWithValue("#ContactMobile", TxtMobile.Text);
cmd.Parameters.AddWithValue("#AreaOfCountry", TxtAreaOfCountry.SelectedValue);
cmd.Parameters.AddWithValue("#UserId", ParameterDirection.Output);
cmd.Parameters.AddWithValue("#AllreadyReg", ParameterDirection.Output);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
Response.Write("line 78");
etc etc
can anyone help
thanks
With the edit: the mistake is using ExecuteReader on a command that doesn't select a data grid - that should be done with ExecuteNonQuery.
The important thing here is how the parameter is added. For example:
var alreadyReg = cmd.CreateParameter();
alreadyReg.Direction = System.Data.ParameterDirection.Output;
alreadyReg.ParameterName = "AllreadyReg";
alreadyReg.DbType = DbType.Int32;
cmd.Parameters.Add(alreadyReg);
//...
cmd.ExecuteNonQuery();
//...
int val = (int)alreadyReg.Value;
Depending on the type of DbCommand object, there may be an overload that accepts all of these in one line - the above assumes just DbCommand. With SqlCommand, you can simplify a bit:
var alreadyReg = cmd.Parameters.Add("AllreadyReg", SqlDbType.Int);
alreadyReg.Direction = ParameterDirection.Output;
//...
cmd.ExecuteNonQuery();
//...
int val = (int)alreadyReg.Value
You might have already handled it, but just in case, make sure to specify direction of parameter in c# code.
Here
cmd.Parameters.AddWithValue("#UserId", ParameterDirection.Output);
wrong usage of AddWithValue. The second parameter is parsed as parameter value, not direction type. Use proper parameter contructor and the add the result to collection.

Retrieving SQL Server output variables in c#

I have a stored procedure:
ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert]
#guidid uniqueidentifier output,
#sname nvarchar(50)
AS
-- INSERT a new row in the table.
INSERT [dbo].[Tbl_Test]
(
[id],
[name]
)
VALUES
(
ISNULl(#guidid, (newid())),
#sname
)
I need the id in C# and put it output in c#:
cmd.Parameters.AddWithValue("#guidid",_id);//_id is SqlGuid
cmd.Parameters.AddWithValue("#sname", "mehdi");
cmd.ExecuteNonQuery();
MessageBox.Show(_id.ToString());
but messagebox show the null value!!
How can I return the id?
I changed it to:
ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert]
#guidid uniqueidentifier output,
#sname nvarchar(50)
AS
DECLARE #NewID UNIQUEIDENTIFIER
SET #NewID = newid();
-- INSERT a new row in the table.
INSERT [dbo].[Tbl_Test]([id], [name]) VALUES(#NewID, #sname);
SET #guidid = #NewID
and C#
SqlParameter outparam = cmd.Parameters.Add("#guidid",SqlDbType.UniqueIdentifier);
outparam.Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("#sname", "mehdi");
cmd.ExecuteNonQuery();
MessageBox.Show(_id.Value.ToString());
but it doesn't return anything
First of all - if it's an OUTPUT parameter, you cannot use .AddWithValue in C# - you need to use:
SqlParameter outParam = cmd.Parameters.Add("#guidid", SqlDbType.Uniqueidentifier);
outParam.Direction = ParameterDirection.Output;
and also, in your T-SQL code, you need to assign the new value to the output parameter!
ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert]
#guidid uniqueidentifier output,
#sname nvarchar(50)
AS
DECLARE #NewID UNIQUEIDENTIFIER
SET #NewID = newid();
-- INSERT a new row in the table.
INSERT [dbo].[Tbl_Test]([id], [name]) VALUES(#NewID, #sname);
SET #guidid = #NewID
Update: if you run this in your SQL Server Mgmt Studio - does it show anything??
DECLARE #insertedID UNIQUEIDENTIFIER
EXEC dbo.pr_Tbl_Test_Insert #guidid = #insertedID OUTPUT,
#sname = N'TestUser' -- nvarchar(50)
SELECT #insertedID
and in your C# - you have to read out the value of the output parameter after calling ExecuteNonQuery!
SqlParameter outparam = cmd.Parameters.Add("#guidid",SqlDbType.UniqueIdentifier);
outparam.Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("#sname", "mehdi");
cmd.ExecuteNonQuery();
Guid newlyInsertedID = new Guid(cmd.Parameters["#guidid"].Value);
MessageBox.Show(newlyInsertedID.ToString());
Before you execute the query you need to specify the direction of the parameter, in this case output. e.g.:
cmd.Parameters.AddWithValue("#guidid",_id);//_id is SqlGuid
cmd.Parameters.AddWithValue("#sname", "mehdi");
cmd.Parameters["#guidid"].Direction = ParameterDirection.Output
cmd.ExecuteNonQuery();
MessageBox.Show(cmd.Parameters["#guidid"].Value.ToString());
You need to construct a SqlParameter using one of the constructors that lets you specify a ParameterDirection, such as this one. Alternatively, construct your parameter and then set the direction using the Direction property.
Check this link on MSDN for more information.
Why are you setting the #guidid uniqueidentifier output as an output parameter? It means it will override it once you execute the stored procedure. If that's your intention, then you need to add a statement after the insert statement to set the output parameter to the value you want. something like this: select #guidid = #generatedID. Yeah look at marc_s code, that's the way you are supposed to do it.
I also found this very frustrating and I could not understand the issue. Although many answers are correct, there was one simple line that was often overlooked by me and others, namely the command needs to be store procedure not just any sql with parameters, so I hope this helps:
cmd.CommandType = CommandType.StoredProcedure;
cmd.Txt should look like this:
#"my_stored_proct "
NOT
#"my_stored_proct #p1, #p2, #p3 out"
So putting it all together. You might want to separate it into several methods. and add TimeOuts etc. However these are what I think are the critical parts that differ from other commands witout output Parameters.
using (SqlCommand cmd= new SqlCommand())
{
cmd.Text= ...;
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter outParam = cmd.Parameters.Add("#guidid", SqlDbType.Uniqueidentifier);
outParam.Direction = ParameterDirection.Output;
using (var connection = new SqlConnection(this.myConnectionString))
{
connection.Open();
cmd.Connection = connection;
try
{
cmd.ExecuteNonQuery();
}
catch
{
// put your sql catches etc. here..
throw;
}
}
var outValue = outParam.Value;
//query outValue e.g. ToString()
}

OdbcCommand on Stored Procedure - "Parameter not supplied" error on Output parameter

I'm trying to execute a stored procedure (against SQL Server 2005 through the ODBC driver) and I recieve the following error:
Procedure or Function 'GetNodeID' expects parameter '#ID', which was not supplied.
#ID is the OUTPUT parameter for my procedure, there is an input #machine which is specified and is set to null in the stored procedure:
ALTER PROCEDURE [dbo].[GetNodeID]
#machine nvarchar(32) = null,
#ID int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM Nodes WHERE NodeName=#machine)
BEGIN
SELECT #ID = (SELECT NodeID FROM Nodes WHERE NodeName=#machine)
END
ELSE
BEGIN
INSERT INTO Nodes (NodeName) VALUES (#machine)
SELECT #ID = (SELECT NodeID FROM Nodes WHERE NodeName=#machine)
END
END
The following is the code I'm using to set the parameters and call the procedure:
OdbcCommand Cmd = new OdbcCommand("GetNodeID", _Connection);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.Add("#machine", OdbcType.NVarChar);
Cmd.Parameters["#machine"].Value = Environment.MachineName.ToLower();
Cmd.Parameters.Add("#ID", OdbcType.Int);
Cmd.Parameters["#ID"].Direction = ParameterDirection.Output;
Cmd.ExecuteNonQuery();
_NodeID = (int)Cmd.Parameters["#Count"].Value;
I've also tried using Cmd.ExecuteScalar with no success. If I break before I execute the command, I can see that #machine has a value.
If I execute the procedure directly from Management Studio, it works correctly.
Any thoughts? Thanks
Try replacing :
OdbcCommand Cmd = new OdbcCommand("GetNodeID", _Connection);
Cmd.CommandType = CommandType.StoredProcedure;
With :
OdbcCommand Cmd = new OdbcCommand("{call GetNodeID(?,?)}", _Connection);
More info :
http://support.microsoft.com/kb/310130
I'm not exactly sure what you mean by
there is an input #machine which is
specified and is set to null in the
stored procedure
In your proc's signature, this line:
#machine nvarchar(32) = null
doesn't mean that you're setting #machine to null inside the proc - it means you're assigning a default value to be used in case the parameter is missing (in this case, null is the value to be used for a missing param).
Getting the error about #ID being missing would happen if you were calling this stored procedure without passing any parameters at all (#machine would not be flagged as a problem since it has a default value defined). Your code example looks fine to me - are you sure the stored proc isn't being called from somewhere else in your program (somewhere where no parameters are being added)?
Stored procedure with input parameters and ODBC Connection:
create a stored procedure:
create procedure proc_name #parm1 varchar(20), #parm2 varchar(10) as begin insert into table_name values(#parm1,#parm2);end
This code works in SQL Server.
private void button1_Click(object sender, EventArgs e)
{
string name = txtname.Text;
string num = txtnum.Text;
OdbcConnection con = new OdbcConnection("dsn=naveenk_m5");
OdbcCommand cmd = new OdbcCommand("{call proc1(?,?)}",con);
cmd.Parameters.Add("#parm1", OdbcType.VarChar).Value=name;
cmd.Parameters.Add("#parm2", OdbcType.VarChar).Value = num;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("inserted a row");
}

Categories

Resources