I'm trying to pull data from an SQL variable in C# to use in another SQL query.
Basically I have a for loop that is running through a datagrid and inserting the data into a table which I need to be linked to #DataID in this query below. As it is in a different query I can't access it so I want to pull it out into a var.
What's the best way to go about this? already searched lots of options and not coming up with anything that works
The help is appreciated!
Cheers
string dartBoxQuery = #"DECLARE #DataID int;
INSERT INTO DartBox (DartBoxNumber, ReturnDate, Comments)
VALUES (#dbn, #rtndate, #cmmts)
SELECT #DataID = scope_identity();";
// set up the command before exec
SqlCommand cmd = new SqlCommand(dartBoxQuery, con);
//set parameters
cmd.Parameters.AddWithValue("#rtndate", dateTimePicker1.Text);
cmd.Parameters.AddWithValue("#dbn", textBox1.Text);
cmd.Parameters.AddWithValue("#cmmts", textBox2.Text);
// call SQL connection
con.Open();
// execute above query
cmd.ExecuteNonQuery();
//close connection
con.Close();
If you want to fetch #DataID back to the caller, there are 3 options:
declare an output parameter... presumably just moving #DataID to be an output parameter rather than a local variable; add an extra parameter and give it the direction of ParameterDirection.Output; after the ExecuteNonQuery, read out the value
at the end of your existing SQL, return #DataID; add an extra parameter and give it the direction of ParameterDirection.ReturnValue; after the ExecuteNonQuery, read out the value
at the end of your existing SQL, select #DataID; use ExecuteScalar and read out the return value
In this case, ExecuteScalar is probably the easiest option:
string dartBoxQuery = #"DECLARE #DataID int;
INSERT INTO DartBox (DartBoxNumber, ReturnDate, Comments)
VALUES (#dbn, #rtndate, #cmmts)
SELECT #DataID = scope_identity();
SELECT #DataID";
// set up the command before exec
SqlCommand cmd = new SqlCommand(dartBoxQuery, con);
//set parameters
cmd.Parameters.AddWithValue("#rtndate", dateTimePicker1.Text);
cmd.Parameters.AddWithValue("#dbn", textBox1.Text);
cmd.Parameters.AddWithValue("#cmmts", textBox2.Text);
// call SQL connection
con.Open();
// execute above query
var dataId = Convert.ToInt32(cmd.ExecuteScalar());
//close connection
con.Close();
Related
In SQL:
INSERT INTO [dbo].[tblFiles]
([FullFilePath]
,[LastModified])
VALUES
('P:\test\test.csv',
null)
This will store the full path in the database :)
However, I need to do this in code.
SqlConnection connection = new SqlConnection(DatabaseHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand( "stpInsertFile", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#filepath", System.Data.SqlDbType.VarChar));
command.Parameters["#filepath"].Value = article.FullFilePath;
command.Parameters.Add(new SqlParameter( "#LastModified", System.Data.SqlDbType.DateTime));
command.Parameters["#LastModified"].Value = article.LastModified;
int newArticleID = Convert.ToInt32((decimal)command.ExecuteNonQuery());
command.Dispose();
connection.Close();
connection.Dispose();
return newArticleID;
With this all I get is 'P' in the full path column.
So I tried using LINQ and got the same result.
public int InsertArticleUsingLINQ(tblFile article) {
DataClassesDataContext context = new DataClassesDataContext();
tblFile newFileEntry = new tblFile();
newFileEntry.FullFilePath = article.FullFilePath;
newFileEntry.LastModified = article.LastModified;
context.tblFiles.InsertOnSubmit(newFileEntry);
context.SubmitChanges();
return newFileEntry.ID;
}
I'm not doing anything with the string before passing it to the database insert functions. I read that you need to escape the backslash but it seems to be escaping on the quote. Also read that you need an # symbol before the sql but how do you add this to a parameter?
warning: since you didn't share the stored procedure code this is just a wild guess.
did you set the size of the #filePath parameter in the definition of your stored procedure?
if you declare it as:
create procedure stpInsertFile
#filepath varchar,
#LastModified datetime
as
...
then you parameter is created as varchar(1) because of the default behaviour of varchar datatype and that would produce the result you get.please check reference documentation for char and varchar datatype on ms website.
if stpInsertFile is a Stored Procedure you will have to set in your code:
...
command.CommandType = CommandType.StoredProcedure;
else you have to set the query string in your command:
SqlCommand command = new SqlCommand( "INSERT INTO [dbo].[tblFiles] ([FullFilePath] [LastModified]) VALUES (#filepath,#LastModified)", connection);
...
Of the above options, the ADO code did not copy the full path, even with manually adding quotes. All I ever got was one character in the database.
On further inspection, the parameter was of type Varchar(1) !!! I changed this to Varchar(255) an it worked.
Note, the LINQ to SQL function did insert the full path as this was not using the Stored Procedure.
Apologies for the mistake.
My SQL Server stored procedure returns a result set from a SELECT statement and has output parameters. When I call this one from C# (connection in made through SqlConnection class) I have a problem: the out parameter returns null. If I comment select statement in procedure than it gets proper result.
CREATE PROC test
#Out INT OUT
AS
BEGIN
SET #Out=4
SELECT * FROM temp_table
END
Does out parameter wait to select statement?
How to fix it?
Added ----->
#huMptyduMpty is right i mentioned only sql procedure for experiment. Now I show changed procedure and code from C# side.
I write this procedure.
CREATE PROC T_Proc
#Count INT = NULL OUT
AS
BEGIN
SET #Count = (SELECT COUNT(*) FROM T_Table AS tt)
--SELECT * FROM T_Table AS tt
END
and this one in C#
SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=test;Integrated Security=True");
SqlCommand cmd = new SqlCommand("T_Proc", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter MyDataAdapter = new SqlDataAdapter();
MyDataAdapter.SelectCommand = cmd;
SqlParameter a1 = cmd.Parameters.Add("#Count", SqlDbType.Int);
a1.Direction = ParameterDirection.Output;
DataSet Mydataset = new DataSet();
conn.Open();
cmd.ExecuteReader();
textBox1.Text = a1.Value.ToString();
conn.Close();
In this situation T_Proc returns result correctly, but if I uncheck this snip from SQL procedure --SELECT * FROM T_Table AS tt than #Count returns null
You can get both a dataset and parameter values, you just need to switch the order: first the dataset, then the parameters.
From MSDN:
Output, InputOut, and ReturnValue parameters returned by calling ExecuteReader cannot be accessed until you close the SqlDataReader.
"A SQL Server stored procedure that you can call is one that returns one or more OUT parameters, which are parameters that the stored procedure uses to return data back to the calling application. "
Read more about Using a Stored Procedure with Output Parameters
So you can do something like
CREATE PROC test
#Out INT OUT
AS
BEGIN
SELECT #Out = FieldName FROM temp_table
END
I suggest you (which i prefer), not to use out put parameter if you going to select multiple columns. You can use a SqlDataReader from your c# code
Also have a look at Stored Procedure, when to use Output parameter vs Return variable
Update
To get the row count, just remove your output parameter and get the count from c# code
i.e.
var reader = cmd.ExecuteReader();
var rowCount = reader.Cast<object>().Count();
Not quite sure what you after
check this one
CREATE PROC T_Proc
AS
BEGIN
Declare #Count INT
SET #Count = (SELECT COUNT(*) FROM T_Table AS tt)
SELECT *, #Count as TotalCount
FROM T_Table AS tt
Where xxxx---condition if you need any
END
I'm working on an ASP.NET project (C#) with SQL Server 2008.
When I insert a row into a table in the database, I would like to get the last inserted ID, which is the table's IDENTITY (Auto Incremented).
I do not wish to use another query, and do something like...
SELECT MAX(ID) FROM USERS;
Because - even though it's only one query - it feels lame...
When I insert something I usually use ExecuteNonQuery(), which returns the number of affected rows.
int y = Command.ExecuteNonQuery();
Isn't there a way to return the last inserted ID without using another query?
Most folks do this in the following way:
INSERT dbo.Users(Username)
VALUES('my new name');
SELECT NewID = SCOPE_IDENTITY();
(Or instead of a query, assigning that to a variable.)
So it's not really two queries against the table...
However there is also the following way:
INSERT dbo.Users(Username)
OUTPUT inserted.ID
VALUES('my new name');
You won't really be able to retrieve this with ExecuteNonQuery, though.
You can return the id as an output parameter from the stored procedure, e.g. #userId int output
Then, after the insert, SET #userId = scope_identity()
even though it's only one query - it feels lame...
It actually is also wrong as you can have multiple overlapping iserts.
That is one thing that I always fuind funny - people not reading the documentation.
SELECT SCOPE_IDENTITY()
returns the last identity value generated in a specific scope and is syntactically correct. It also is properly documented.
Isn't there a way to return the last inserted ID without using another query?
Yes. Ask for the number in the saame SQL batch.
INSERT (blablab9a); SELECT SCOPE_IDENTITY ();
as ONE string. ExecuteScalar.
You can have more than one SQL statement in one batch.
If you want to execute query from C# code & want to get last inserted id then you have to find the following code.
SqlConnection connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
connection.Open();
string sql = "Insert into [Order] (customer_id) values (" + Session["Customer_id"] + "); SELECT SCOPE_IDENTITY()";
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
var order_id = cmd.ExecuteScalar();
connection.Close();
Console.Write(order_id);
I'm new in C# programming, so I'll appreciate if anyone can help me. I know there are similar question but I still can't find the solution for my problem. I'm developing a mock system, where when user bought the product, the system will store all the transaction details. the problem is, I cannot insert the data into the database. Here's the code:
using (SqlConnection conn = new SqlConnection
(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
{
string QueryA = "#Insert into TransDetails(AccountNumber,Amount,Provider"
+ ",Mobile Number,TransNum,TransDate, Status) "
+ " Values (#AccountNumber,#Amount,#Provider,#Mobile Number,"
+ "#TransNum,#TransDate,#Status";
using (SqlCommand cmd = new SqlCommand("InsertRecord", conn))
{
conn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = QueryA;
cmd.Parameters.AddWithValue("#AccountNumber", acc.Text);
cmd.Parameters.AddWithValue("#Amount", lblAmount.Text);
cmd.Parameters.AddWithValue("#Provider", lblProvider.Text);
cmd.Parameters.AddWithValue("#Mobile Number", lblNumber.Text);
cmd.Parameters.AddWithValue("#TransNum", lblTrans.Text);
cmd.Parameters.AddWithValue("#TransDate", lblDate.Text);
cmd.Parameters.AddWithValue("#Status", status.Text);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch
{
lblMessage.Text = "Error";
}
finally
{
conn.Close();
}
}
}
and the stores procedures are as follows:
ALTER PROCEDURE InsertRecord1
#AccountNumber int,
#Amount nchar(10),
#Provider nchar(10),
#MobileNumber int,
#TransNum nchar(10),
#TransDate date,
#Status nchar(10)
AS
Insert into TransDetails(AccountNumber,Amount,Provider,MobileNumber,TransNum,TransDate,Status)
Values (#AccountNumber,#Amount,#Provider,#MobileNumber,#TransNum,#TransDate,#Status)
return
Really appreciate any help.
P/S: i dont know why the beginning of the stored procedures started with "alter".
I may be reading it wrong, but it looks like your stored procedure is not used at all. Try commenting out "cmd.CommandText = QueryA;" and substitute "cmd.CommandText = "InsertRecord1";" and change CommandType to StoredProcedure.
QueryA, by the way, is missing a paren at the end. However, the whole thing is unnecessary since you have a stored procedure that does the same thing and it's almost always preferable to use a stored procedure rather than embedded DML.
You must escape Mobile Number while brackets
Insert into TransDetails(AccountNumber,Amount,Provider,[Mobile Number],...
and remove the space in your parameter
...,#MobileNumber,#TransNum,#TransDate,#Status
and change the paramname in your command parameter
cmd.Parameters.AddWithValue("#MobileNumber", lblNumber.Text);
but seeing your stored procedure, the column Mobile Number has no space between it. Is it a typo error in your query on QueryA? If it is, then remove the space on it (also on parameter name)
Insert into TransDetails(AccountNumber,Amount,Provider,MobileNumber,...
or
change your CommandType.Text to CommandType.StoredProcedure and remove this line,
cmd.CommandText = QueryA;
You're using the wrong overload of the SqlCommand constructor. According to MSDN:
new SqlCommand(string, SqlConnection) Initializes a new instance of the SqlCommand class with the text of the query and a SqlConnection.
What you need to do is either set your CommandType for the sql command to CommandType.StoredProcedure and not use QueryA, or initialize the sql command with QueryA and not make use of your stored procedure.
As you can see there is # at the start of your SQL Statement.
Also you are not really using the Store Procedure.
You can Try this:
using (SqlConnection conn = new SqlConnection (ConfigurationManager.ConnectionStrings["database"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("InsertRecord1", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#AccountNumber", acc.Text);
cmd.Parameters.AddWithValue("#Amount", lblAmount.Text);
cmd.Parameters.AddWithValue("#Provider", lblProvider.Text);
cmd.Parameters.AddWithValue("#Mobile Number", lblNumber.Text);
cmd.Parameters.AddWithValue("#TransNum", lblTrans.Text);
cmd.Parameters.AddWithValue("#TransDate", lblDate.Text);
cmd.Parameters.AddWithValue("#Status", status.Text);
try
{
cmd.ExecuteNonQuery();
}
catch
{
lblMessage.Text = "Error";
}
finally
{
conn.Close();
}
}
Tho I don't use SQL Commands, Adapters...etc. to access the data from the SQL Database. I prefer Microsoft Data Access ApplicationBlocks which is easy-to-use library provided by Microsoft to access data from SQL Server.
Download
You can download it here http://download.microsoft.com/download/VisualStudioNET/daabref/RTM/NT5/EN-US/DataAccessApplicationBlock.msi
Introduction
https://web.archive.org/web/20210304123854/https://www.4guysfromrolla.com/articles/062503-1.aspx
I'm writing a method to insert a Student into a local SQL database that contains a table with information about Students:
public void AddStudent(string name, string teachName, string pass)
{
string dbfile = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\Logo.sdf";
SqlCeConnection connection = new SqlCeConnection("Data Source=" + dbfile + "; Password = 'dbpass2011!'");
connection.Open();
SqlCeTransaction transaction = connection.BeginTransaction();
SqlCeCommand command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = "INSERT INTO Students VALUES ('#name', '#id', '#pass', '#tname')";
command.Parameters.Add("#name", name);
command.Parameters.Add("#id", this.ID);
command.Parameters.Add("#pass", MD5Encrypt.MD5(pass));
command.Parameters.Add("#tname", teachName);
command.Prepare();
command.ExecuteNonQuery();
transaction.Commit();
connection.Dispose();
connection.Close();
}
Whenever I use this, it never inserts the data to the table when I look at the contents of the Students table in the database. Originally I had this return an int so I could see how many rows it affected, which it always returned 1, so I know it's working.
I've looked for answers to this, and the answer to similar questions was that the person asking was looking at the wrong .sdf file. I've made sure that I'm looking at the right file.
Any feedback would be much appreciated!
command.CommandText = "INSERT INTO Students VALUES ('#name', '#id', '#pass', '#tname')";
You should remove the extra single quotes - this should be:
command.CommandText = "INSERT INTO Students VALUES (#name, #id, #pass, #tname)";
Also I am not sure why you open a transaction for a single insert - that is also not needed.
You don't need to put single quote to parametrized query, in case of parametrized query the whole data will be parsed as required,
command.CommandText = "INSERT INTO Students VALUES (#name, #id, #pass, #tname)";
Also, its better to set parameter type, size and value explicitly as below:
SqlCeParameter param = new SqlCeParameter("#name", SqlDbType.NVarChar, 100);
param.Value = name; // name is a variable that contain the data of name field
//param.Value = 'Jhon Smith'; //Directly value also can be used
Hope this would be helpful, thanks for your time.
There is most likely an exception being raised in your code; you need to add a try/catch handler and/or debug the application to figure out exactly what is happening.
However, there are at least two issues with your code:
The prepare statement requires the data types of the parameters. From the MSDN documentation:
Before you call Prepare, specify the data type of each parameter in the statement to be prepared. For each parameter that has a variable-length data type, you must set the Size property to the maximum size needed. Prepare returns an error if these conditions are not met.
You need to close the connection before disposing it (this won't affect the insert, however).