I am getting following error when calling a stored procedure in SQL Server from C#:
Line 1: Incorrect syntax near 'spGet_Data'.
Here is my code:
public string GetData (string destinationFile)
{
string conectionString = "uid=One_User;pwd=One_Password;database=One_Database;server=One_Server";
SqlConnection con = new SqlConnection(conectionString);
SqlCommand sqlCmd = new SqlCommand();
string returnValue = string.Empty;
string procedureName = "spGet_Data";
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd = new SqlCommand(procedureName, con);
sqlCmd.Parameters.AddWithValue("#FileName", destinationFile);
con.Open();
var returnParameter = sqlCmd.Parameters.Add("#ret", SqlDbType.VarChar);
returnParameter.Direction = ParameterDirection.ReturnValue;
sqlCmd.ExecuteNonQuery();
returnValue = returnParameter.Value.ToString();
con.Close();
return returnValue;
}
Procedure itself returning data properly, I checked connection it is in Open state.
What else it can be?
Thank you.
The problem lies in the fact that you create the command two times.
After the first initialization you set correctly the CommandType to StoredProcedure, but once again you created the command and this time you forgot to set the CommandType
Just remove the first initialization, leave only the second one and move the CommandType setting after the initialization
SqlConnection con = new SqlConnection(conectionString);
string returnValue = string.Empty;
string procedureName = "spGet_Data";
SqlCommand sqlCmd = new SqlCommand(procedureName, con);
sqlCmd.CommandType = CommandType.StoredProcedure;
You create a SqlCommand object, then set it's CommandType property, then overwrite it by calling new on your command object again. Written out correctly, your code should look like this:
public string GetData (string destinationFile)
{
string conectionString = "uid=One_User;pwd=One_Password;database=One_Database;server=One_Server";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand sqlCmd = new SqlCommand(procedureName, con);
sqlCmd.CommandType = CommandType.StoredProcedure;
string returnValue = string.Empty;
string procedureName = "spGet_Data";
sqlCmd.Parameters.AddWithValue("#FileName", destinationFile);
con.Open();
var returnParameter = sqlCmd.Parameters.Add("#ret", SqlDbType.VarChar);
returnParameter.Direction = ParameterDirection.ReturnValue;
sqlCmd.ExecuteNonQuery();
returnValue = returnParameter.Value.ToString();
con.Close();
return returnValue;
}
Also, I would highly suggest that you surround your SqlConnection and SqlCommand objects with the Using Statement. Much like this:
public string GetData (string destinationFile)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand sqlCmd = new SqlCommand(procedureName, con))
{
}
}
}
The benefit of doing it this way is cleaner code and since your command and connection objects implement IDisposable, they will be handled by GC once they fall out of scope.
By the way, you have 'conectionString' misspelled; I fixed it in my code examples.
Whoops. This is being done, albeit incorrectly. See the other answer.
See SqlCommand.CommandType. You need to tell it to be treated as an sproc call. E.g.
sqlCmd.CommandType = CommandType.StoredProcedure;
Otherwise it results in an invalid SQL statement (i.e. running spGet_Data verbatim in an SSMS query should produce a similar messages).
Related
I need to know why I am still getting this error
Stored procedure expects parameter which was not supplied
But I am actually sending this parameter.
The stored procedure in the database looks like this:
CREATE PROCEDURE SVC_BUSCA_MEDIO_LANDING
(#rut VARCHAR)
AS
BEGIN
SELECT utm_source
FROM landing_formulario
WHERE rut = #rut
END
And my .net code:
string result = string.Empty;
string connString = System.Configuration.ConfigurationManager.AppSettings["StPazWeb"].ToString();
string SVC_BUSCA_MEDIO_LANDING = "SVC_BUSCA_MEDIO_LANDING";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
try
{
SqlCommand command = new SqlCommand(SVC_BUSCA_MEDIO_LANDING);
command.CommandType = CommandType.StoredProcedure;
command = new SqlCommand(command.CommandText, connection);
command.Parameters.AddWithValue("#rut", rut);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
result = (string)reader["utm_source"];
}
}
catch (SqlException ex)
{
throw new Exception("Oops!." + ex.Message);
}
}
return result.ToString();
Any idea what can be happening?
For some reason you create the command twice, with the second instantiation replacing the first, however on the second one you don't set the command type, and as a result your parameter is being ignored.
Try:
SqlCommand command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = SVC_BUSCA_MEDIO_LANDING;
command.Parameters.AddWithValue("#rut", rut);
You're using:
SqlCommand command = new SqlCommand(SVC_BUSCA_MEDIO_LANDING);
but you're reseting the command at:
command = new SqlCommand(command.CommandText, connection);
Try instead:
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "SVC_BUSCA_MEDIO_LANDING";
command = new SqlCommand(command.CommandText, connection);
command.Parameters.AddWithValue("#rut", rut);
I am super newbie with Visual Studio. I want to create an application form in Visual Studio to insert data into my T-SQL database.
I have created a very simple Windows Application Form. It takes data from fields and insert them into my database. it simple and it works.
Now, what i want to do is to add the function for the app to look if values already exists in the database, so it wont create duplicates.
What im looking for to be checked is first_name, last_name and dob.
as im super newbie, i added an if statement to the Submit button (on click) like below:
private void btnSubmit_Click(object sender, EventArgs e)
{
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("UserInterface", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
if (txtFirstName == sqlCmd.CommandText("EXISTS first_name FROM employee"))
MessageBox.Show("already exists");
}
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("UserInterface", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("#first_name", txtFirstName.Text.Trim());
sqlCmd.Parameters.AddWithValue("#last_name", txtLastName.Text.Trim());
sqlCmd.Parameters.AddWithValue("#dept_id", txtDepartmentID.Text.Trim());
sqlCmd.Parameters.AddWithValue("#job_title", txtJobTitle.Text.Trim());
sqlCmd.Parameters.AddWithValue("#dob", dateDOB.Text);
sqlCmd.Parameters.AddWithValue("#start_date", dateStartDate.Text);
sqlCmd.Parameters.AddWithValue("#contract_type", txtContractType.Text.Trim());
sqlCmd.Parameters.AddWithValue("#status_code", txtStatusCode.Text.Trim());
sqlCmd.Parameters.AddWithValue("#effect_date", dateEffectDate.Text);
sqlCmd.ExecuteNonQuery();
MessageBox.Show("Insertion Successful");
Clear();
}
}
void Clear()
{
txtFirstName.Text = txtLastName.Text = txtJobTitle.Text = txtDepartmentID.Text = txtContractType.Text = txtStatusCode.Text = "";
dateDOB.Text = dateEffectDate.Text = dateStartDate.Text = "";
}
obviously I'm very new and it does not work.
How can i go ahead and do this?
A few things to mention on this portion:
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand("UserInterface", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
if (txtFirstName == sqlCmd.CommandText("EXISTS first_name FROM employee"))
MessageBox.Show("already exists");
}
A SqlCommand object can have several command types, 2 of which are CommandType.StoredProcedure (which you used to insert your new records) and CommandType.Text which is used to supply plain SQL directly. For this case you want to set it as plain text so change that line to:
sqlCmd.CommandType = CommandType.Text;
The first parameter of the constructor of the SqlCommand is the command text. If the command is gonna be a stored procedure call, then you need to pass the SP name (which you've done when inserting your new row), but if you want plain SQL then you can write it here (I modified the SQL to actually search for the first name in a safe way, preventing SQL Injection):
SqlCommand sqlCmd = new SqlCommand("SELECT first_name FROM employee WHERE first_name = #firstName", sqlCon);
DbParameter firstNameParameter = new SqlParameter("#firstName", txtFirstName.Text.Trim());
sqlCmd.Parameters.Add(firstNameParameter);
You need to execute the command with the ExecuteReader() method, and this will return a reader object you need to use to retrieve it's results (the SQL might return several rows).
using (DbDataReader reader = sqlCmd.ExecuteReader())
while (reader.Read())
{
MessageBox.Show("already exists");
break;
}
This is a head-start so you can keep on coding, many things to improve yet but might be too much if explained all of a sudden.
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
SqlCommand sqlCmd = new SqlCommand("SELECT first_name FROM employee WHERE first_name = #firstName", sqlCon);
DbParameter firstNameParameter = new SqlParameter("#firstName", txtFirstName.Text.Trim());
sqlCmd.Parameters.Add(firstNameParameter);
sqlCmd.CommandType = CommandType.Text;
sqlCon.Open();
using (DbDataReader reader = sqlCmd.ExecuteReader())
while (reader.Read())
{
MessageBox.Show("already exists");
break;
}
}
I'm new in c# and want to call store procedure in the sql server database ,for that purpose write this code:
using (SqlConnection con = new SqlConnection("Data Source=ipaddress;Initial Catalog=database;User ID=userid;Password=password;"))
{
using (SqlCommand cmd = new SqlCommand("exec web.sp_getTotalBillPayam "+Convert.ToInt64(phoneNumber) +",'"+password.Trim()+"',72107603,1067", con))
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
...
when run that code every thing is ok but store procedure not return to me any result ,goto debug i realized in this line run:
SqlDataReader reader = cmd.ExecuteReader();
but debugger not go to the next line of code and wait that line run finish,after 5 min that line not finish and dont go next line of code,what happen?How can i solve that problem?thanks.
Your command is not attached to your connection-- and your use of parameters is dangerous. Try this instead:
EDIT: Sorry, your command is attached to the connection, didn't see that being passed in. Either way, this is the correct pattern for calling a stored proc
using (SqlConnection con = new SqlConnection("Data Source=ipaddress;Initial Catalog=database;User ID=userid;Password=password;")) {
con.Open();
using (SqlCommand cmd = con.CreateCommand()) {
cmd.CommandText = "web.sp_getTotalBillPayam";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
//repeat this for each parameter
var parameter = cmd.CreateParameter();
parameter.ParameterName = "PhoneNumber"; //this must match whatever your parameters are to your stored proc
parameter.DbType = System.Data.DbType.Int64;
parameter.Direction = System.Data.ParameterDirection.Input;
parameter.Value = phoneNumber;
cmd.Parameters.Add(parameter);
...
//if you have an OUTPUT result from your proc, add a a parameter called RETURNS with a direction of ParameterDirection.Return and check value AFTER executing
using (SqlDataReader reader = cmd.ExecuteReader()) {
//if your results are a SELECT query they will be here
}
}
}
For reference, this page (add.ashx.cs), is an add page to a database.
What I'm trying to do is :
figure out how to execute string queryID, and then
store the results of queryID
I'm a bit new at this, but this is what I'm working with so far. Am I on the right path, and what should I change? I don't believe the code below includes storing the results, but just executing queryID.
// new query to get last ID value
// store the command.executeNonQuery results into a variable
string queryID = "SELECT TOP (1) IDENT_CURRENT('dbo.license_info') FROM dbo.license_info";
// first: look up how to execute queryID
// then: store results of query ^
// execute queryID? (section below)
SqlConnection sqlConnection1 = new SqlConnection(queryID);
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "Select * FROM queryID";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// data is accessible through the datareader object here
sqlConnection1.Close();
There are some things missmatched in your code sample. First queryID is your actual query. Second in SqlConnection you need to provide a connection string, that connects to your database (SQL Server, ACCESS, ...). A valid example could look like this:
// this is just a sample. You need to adjust it to your needs
string connectionStr = "Data Source=ServerName;Initial Catalog=DataBaseName;Integrated Security=SSPI;";
SqlConnection sqlConnection1 = new SqlConnection(connectionStr);
SqlCommand cmd = new SqlCommand(sqlConnection1 );
SqlDataReader reader;
cmd.CommandText = "SELECT TOP (1) IDENT_CURRENT('dbo.license_info') FROM dbo.license_info";
cmd.CommandType = CommandType.Text;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
List<string> results = new List<string>();
if(reader.HasRows)
{
while(reader.Read())
{
results.Add(reader[0].ToString());
}
}
sqlConnection1.Close();
Another thing is, that you execute a reader but only select one single value. You can perfectly use ExecuteScalar for that:
// this is just a sample. You need to adjust it to your needs
string connectionStr = "Data Source=ServerName;Initial Catalog=DataBaseName;Integrated Security=SSPI;";
SqlConnection sqlConnection1 = new SqlConnection(connectionStr);
SqlCommand cmd = new SqlCommand(sqlConnection1 );
cmd.CommandText = "SELECT TOP (1) IDENT_CURRENT('dbo.license_info') FROM dbo.license_info";
cmd.CommandType = CommandType.Text;
sqlConnection1.Open();
string result = cmd.ExecuteScalar().ToString();
sqlConnection1.Close();
One last thing. You should use objects that implement IDisposable in a using block. This way the will be removed from memory when they are no longer needed:
// this is just a sample. You need to adjust it to your needs
string connectionStr = "Data Source=ServerName;Initial Catalog=DataBaseName;Integrated Security=SSPI;";
using(SqlConnection sqlConnection1 = new SqlConnection(connectionStr))
{
SqlCommand cmd = new SqlCommand(sqlConnection1 );
cmd.CommandText = "SELECT TOP (1) IDENT_CURRENT('dbo.license_info') FROM dbo.license_info";
cmd.CommandType = CommandType.Text;
sqlConnection1.Open();
string result = cmd.ExecuteScalar().ToString();
}
I am having a problem with an Output parameter in C#/Oracle. I have isolated the code that I need to get working.
This is part of a much larger SQL statement, so do not worry too much if it doesn't make sense. In short I need to copy a row, give it a new ID and return that new ID. I tried using "RETURNING" which did not work. I see no reason why the code below should not work, but I'm getting an "ORA-01036: illegal variable name/number" error. Can anyone see what I'm doing wrong?
using (OracleConnection conn = new OracleConnection(connString))
{
// Open connection and create command.
conn.Open();
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("outValue", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.CommandText = "SELECT seq.nextval INTO :outValue FROM dual";
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
// This is just to see the exception when it fails.
}
}
}
The name of the parameter doesn't match.
cmd.Parameters.Add(":outValue", OracleType.Int32).Direction.......;
^
I have also seen this variation on the query syntax
"BEGIN SELECT seq.nextval INTO :outValue FROM dual END;"
You are using named parameters. Try setting:
cmd.BindByName = true;
Have you tried 'returning' keyword like this?
This code works for me.
using (OracleConnection conn = new OracleConnection(connString))
{
// Open connection and create command.
conn.Open();
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("outValue", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.CommandText = "insert into table (id, value) values (seq.nextval, 'value') returning id into :outValue";
cmd.ExecuteNonQuery();
}
}