Cannot insert numeric value into my SQL table - sql

I currently have 2 tables in my database, 1 with an autonumeric value called ZoekcriteriaID which is the primary key off the table Zoekcriteria.
I want to add the primary key (ZoekcriteriaID) to my other table called Resultaten as a forgeign key but I keep getting the same error.
It seems like cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID)); keeps trying to add the entire query as a numeric value and I can't seem to figure out why.
Could anyone help me?
namespace Proftaak
{
class Mysearch
{
public string zoekterm = "";
int resultaat = 1;
public string Zoekterm
{
get
{
return zoekterm;
}
set
{
zoekterm = value;
}
}
public void InsertZoekcriteria()
{
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
Persist Security Info=False;";
connection.Open();
string sqlstring = "INSERT INTO Zoekcriteria (ZoekCriteria) values ('" + Zoekterm + "')";
OleDbCommand cmd = new OleDbCommand(sqlstring, connection);
cmd.ExecuteNonQuery();
connection.Close();
}
public void searchding()
{
const string apiKey = "AIzaSyDIm9ZOWD8Zd-2tHy5r3c0R-_XjdEFaXGE";
const string searchEngineId = "003470263288780838160:ty47piyybua";
string query = zoekterm;
CustomsearchService customSearchService = new CustomsearchService(new Google.Apis.Services.BaseClientService.Initializer() { ApiKey = apiKey });
Google.Apis.Customsearch.v1.CseResource.ListRequest listRequest = customSearchService.Cse.List(query);
listRequest.Cx = searchEngineId;
Search search = listRequest.Execute();
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\martijn\Dropbox\Proftaak Periode 2 Identity\Database11.accdb;
Persist Security Info=False;";
connection.Open();
string sqlZoekcriteriaID = "SELECT ZoekcriteriaID from Zoekcriteria where Zoekcriteria='" + query + "'";
OleDbCommand cmdZoekcriteria = new OleDbCommand(sqlZoekcriteriaID, connection);
cmdZoekcriteria.ExecuteNonQuery();
foreach (var item in search.Items)
{
string sqlstring1 = #"INSERT INTO Resultaat (ResultatenID,ZoekcriteriaID, Titel, Webadress) VALUES (#ResultatenID,#ZoekcriteriaID, #Titel, #Webadress)";
OleDbCommand cmd1 = new OleDbCommand(sqlstring1, connection);
cmd1.Parameters.AddWithValue("#ResultatenID", resultaat);
cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID));
cmd1.Parameters.AddWithValue("#Titel", item.Title);
cmd1.Parameters.AddWithValue("#Webadress", item.Link);
// string sqlstring2= "INSERT INTO Resultaat(Titel) values ('"+item.Title+"')";
// OleDbCommand cmd2 = new OleDbCommand(sqlstring2, connection);
resultaat++;
cmd1.ExecuteNonQuery();
}
connection.Close();

That's because it does:
string sqlZoekcriteriaID = "SELECT ZoekcriteriaID from Zoekcriteria where Zoekcriteria='" + query + "'";
cmd1.Parameters.AddWithValue("#ZoekcriteriaID",Convert.ToInt32(sqlZoekcriteriaID));
What you want is use the result of the query. What you should do is described in the answer to this question.
You should also rethink the naming of your variables; queryis not a query, for example, just a search condition.

Before close the connection, recover the identity number, like this:
OleDbCommand cmd = new OleDbCommand(sqlstring, connection);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT ##IDENTITY";
integer ZoekcriteriaID = cmd.ExecuteScalar()
connection.Close();
Than you can use the ZoekcriteriaID on the other insert.
Refer to this link

Related

Can't use retrieved data from one query into another one?

I need to use a variable (edifcodigo) which assigned value is retrieved from one query to insert it in a table by using other query but there is a error that says this variable is not available in actual context. I'm kind of new in aspnet, could anybody know how to figure this out?
This is the code I have:
//Connect to db
string connetionString = #"myconexionstring";
string sql = "SELECT TOP 1 id_proyecto AS codigo FROM DNN_SCO_PROY_CO_PROYECTO_TBL WHERE nombre_proyecto= '"+ uedif +"'";
//find building code by querying the database
try
{
using (SqlConnection conexion = new SqlConnection(connetionString))
{
conexion.Open();
using (SqlCommand query = new SqlCommand(sql, conexion))
{
SqlDataReader result = query.ExecuteReader();
while (result.Read())
{
string edifcodigo = result["codigo"].ToString();
}
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
//Save referer friend
try
{
using (SqlConnection conn = new SqlConnection(connetionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("DNN_SVI_SCO_DATOS_RECOMIENDA_AMIGO_SP", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#DRA_PROYECTO_CLIENTE", System.Data.SqlDbType.VarChar).Value = edifcodigo; ;
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
That's because you declared the variable inside a different code block. Every time you open a curly bracket, you open a new code block. Every time you close the curly bracket, you close the current code block. Each code block have it's own scope - it can access variables declared in the surrounding code block, but not variables declared in "sibling" code blocks.
Also, please read about parameterized queries and how they protect you from SQL injection, and change your queries accordingly.
Also, you don't need to close the connection between the two commands, and you can reuse a single command instance in this case. Here is an improved version of your code:
//Connect to db
var connetionString = #"myconexionstring";
var sql = "SELECT TOP 1 id_proyecto AS codigo FROM DNN_SCO_PROY_CO_PROYECTO_TBL WHERE nombre_proyecto = #nombre_proyecto";
//find building code by querying the database
try
{
using (var conexion = new SqlConnection(connetionString))
{
conexion.Open();
using (var cmd = new SqlCommand(sql, conexion))
{
cmd.Parameters.Add("#nombre_proyecto", SqlDbType.NVarChar).Value = uedif;
var edifcodigo = cmd.ExecuteScalar();
//Save referer friend
cmd.Parameters.Clear();
cmd.CommandText = "DNN_SVI_SCO_DATOS_RECOMIENDA_AMIGO_SP";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#DRA_PROYECTO_CLIENTE", System.Data.SqlDbType.VarChar).Value = edifcodigo; ;
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
You are declaring the string variable inside your while loop, it loses scope once you exit the while loop, move it's declaration above with:
string connetionString = #"myconexionstring";
string sql = "SELECT TOP 1 id_proyecto AS codigo FROM DNN_SCO_PROY_CO_PROYECTO_TBL WHERE nombre_proyecto= '"+ uedif +"'";
string edifcodigo = "";
You are trying to use a variable that declared in another scope. edifcodigo should be declared in the parent scope of both try blocks.
//Connect to db
string connetionString = #"myconexionstring";
string sql = "SELECT TOP 1 id_proyecto AS codigo FROM DNN_SCO_PROY_CO_PROYECTO_TBL WHERE nombre_proyecto= '"+ uedif +"'";
string edifcodigo=""; // YOU SHOULD DECLARE edifcodigo HERE
and than rest of code will come
//find building code by querying the database
try
{
using (SqlConnection conexion = new SqlConnection(connetionString))
{
conexion.Open();
using (SqlCommand query = new SqlCommand(sql, conexion))
{
SqlDataReader result = query.ExecuteReader();
while (result.Read())
{
edifcodigo = result["codigo"].ToString();
}
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
//Save referrer friend
try
{
using (SqlConnection conn = new SqlConnection(connetionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("DNN_SVI_SCO_DATOS_RECOMIENDA_AMIGO_SP", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#DRA_PROYECTO_CLIENTE", System.Data.SqlDbType.VarChar).Value = edifcodigo; ;
}
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}

SQL Data Reader into Label - Value doesn't display

DB-Acess.cs
This is where the Public SqlDataReader getEmail is initialised.
public SqlDataReader getEmail(string UserName)
{
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
while (reader.Read())
{
string email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return reader;
}
I'm using OOP and calling the function in asp.net page and want to display the value in a label. Below is the code I'm using to call the function.
SqlDataReader reader = dba.getEmail(pname);
lblEmail.Text = reader.ToString();
lblEmail.DataBind();
Instead of seeing the Email address of the Employee i'm seeing System.Data.SqlClient.SqlDataReader
Please help in correcting this error.
Thank you in advance.
So there are so many issues going on, I decided to write this comment as the beginning to an appropriate solution.
First your method is called getEmail -- shouldn't it return the email (in other words, a string instead).
public string GetEmail(string UserName)
{
string email = string.Empty;
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
while (reader.Read())
{
email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return email;
}
Then all you have to do is:
lblEmail.Text = db.GetEmail(pname);
That should at least get you going. You should also look into using parameterized queries as well as the using statement.
Why do we always prefer using parameters in SQL statements?
There are a few things going wrong here:
1) You are setting the string email to the value of the reader. Which because you are declaring it inside the reader, will never be able to be used. You will lose scope immediately.
2) You are doing this:
lblEmail.Text = reader.ToString();
lblEmail.DataBind();
This is setting the label to the name of the reader (the instance), not the value the reader is producing. No reason to bind, either.
A better way to do it is
lblEmail.Text = email;
Make sure you declare the email variable outside the reader
ERRORS
Return type of the function getEmail is SqlDataReader and you are expecting String i.e. an Email.
Declaration of email in string email = reader["EMPLOYEE.Email"].ToString(); is inside while loop. Therefore, email becomes local to the while loop. It will not recognize outside the loop.
And you are returning reader' an instance ofSqlDataReader,but you were expecting aString`.
In you second code block, what your doing is not wrong(it won't give error) but that is not what you are expecting to get. You should be declaring a String variable eg. email and assign the function to it(or you can directly assign it to lblEmail Text property.
SUGGESTION
The way you are checking ConnectionState in if(conn.State.ToString() == "Closed") may give you the desired result but is not recommended. Instead you should check like this if (conn.State == ConnectionState.Closed).
Now the most awaiting part: The improvised code: lol!
UPDATE
public string getEmail(string UserName){
if (conn.State == ConnectionState.Closed){
conn.Open();
}
//string noemail ="noemailsaved";
string email="";
using(SqlCommand newCmd = new SqlCommand()){
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email From dbo.EMPLOYEE Where Username = #uname";
newCmd.Parameters.AddWithValue("#uname",UserName);
using(SqlDataReader reader = newCmd.ExecuteReader()){
while (reader.Read()){
email = reader["Email"].ToString();
}
}
}
conn.Close();
//reader.Close();
return email ;
}
For setting the Label Text
lblEmail.Text = dba.getEmail(pname);
Yes that's cause you are calling ToString() on reader object and thus it just printing the classname fully qualified reader.ToString().
Moreover, you are dong it wrong. Current code shouldn't work since you are returning reader which has already been closed and thus you can't read from it. Rather, you should change your method to return the email and use it like
public string getEmail(string UserName)
{
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
// Hopefully your query returns a single email record
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
string email = string.Empty;
while (reader.Read())
{
email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return email;
}
Moreover if your query returns a single email value then use ExecuteScalar() rather like
string email = newCmd.ExecuteScalar() as string;
Now you can assign it in caller
lblEmail.Text = dba.getEmail(pname);
string q,d;
int ano=0;
SqlConnection con = new SqlConnection("Data Source=SANDEESQLEXPRESS;Initial Catalog=agent demo;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("select * from po where agentno=#ano", con);
cmd.Parameters.AddWithValue("ano",ano);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
d = dr["date1"].ToString();
}
dr.Close();
Label1.Text = d+ "";
does not show value of date in lablel

I am having trouble with my web service in ASP.NET

I have written a webservice to access my SQL database.
[WebMethod]
public void getRoomByBuildingID(int buildingID)
{
string cs = ConfigurationManager.ConnectionStrings["vetDatabase_Wizard"].ConnectionString;
List<Room> rooms = new List<Room>();
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("spGetRoomsByBuildingID", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter()
{
ParameterName = "#buildingID",
Value = buildingID
};
cmd.Parameters.Add(param);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Room room = new Room();
room.ID = Convert.ToInt32(rdr["ID"]);
room.Name = rdr["Room"].ToString();
room.buildingID = Convert.ToInt32(rdr["Building"]);
rooms.Add(room);
}
}
JavaScriptSerializer js = new JavaScriptSerializer();
//Serialize list object into a JSON array and write in into the response stream
Context.Response.Write(js.Serialize(rooms));
}
I keep getting an indexOutOfRangeException at
room.building = Convert.ToInt32(rdr["Building"]);
I've been looking at my sql table, and the column names and types are correct (i.e. ID, Room, Building). I am totally clueless at this point and would greatly appreciate the community's feedback. Thank you!
EDIT:
ALTER PROCEDURE spGetRoomsByBuildingID
#buildingID int
AS
BEGIN
SELECT ID, Room, Building FROM tblRooms
WHERE Building = #buildingID
END
EXEC spGetRoomsByBuildingID

I am updating Image fields in my SQL table using Asp.net. It give me a multi-part Identifier bound error

I am storing the users current Identity in the user name variable, and using that variable to compare inside the query!
protected void btnUpload_Click(object sender, EventArgs e)
{
string constr = "Data Source=Talhamalik\\sqlexpress;Initial Catalog=Moodee;Integrated Security=True";
int length = FileUpload1.PostedFile.ContentLength;
byte[] pic = new byte[length];
FileUpload1.PostedFile.InputStream.Read(pic, 0, length);
string Username = Page.User.Identity.Name.Trim();
using (SqlConnection con = new SqlConnection(constr))
{
try
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
//calling connection method
//inserting uploaded image query
SqlCommand com = new SqlCommand("Update Users Set Image=#Image, ImageName =#Name where [Email] =" + Username, con);
com.Parameters.AddWithValue("#Image", pic);
com.Parameters.AddWithValue("#Name", Path.GetFileName(FileUpload1.PostedFile.FileName));
com.Connection = con;
con.Open();
com.ExecuteNonQuery();
}
}
finally
{
con.Close();
}
}
}
I think you need to surround username with quotes
Try this
SqlCommand com = new SqlCommand("Update Users Set Image=#Image, ImageName =#Name
where [Email] ='" + Username+"'", con);
Why not use a parameter for the username value as well, it will protect you against sql-injection,,,,,, something like....
SqlCommand com = new SqlCommand("Update Users Set Image=#Image, ImageName =#Name where [Email] = #Username", con);
com.Parameters.AddWithValue("#Image", pic);
com.Parameters.AddWithValue("#Name", Path.GetFileName(FileUpload1.PostedFile.FileName));
com.Parameters.AddWithValue("#Username", Username);
com.Connection = con;

Retrieve SQL Statement Does Not Go Into While Loop

I am having problem when doing retrieve function in 3-tier in C#. Here is the codes:
public DistributionStandardPackingUnits getSPUDetail(string distributionID)
{
DistributionStandardPackingUnits SPUFound = new DistributionStandardPackingUnits();
using (var connection = new SqlConnection(FoodBankDB.connectionString))
{
SqlCommand command = new SqlCommand("SELECT name, description, quantity FROM dbo.DistributionStandardPackingUnits WHERE distribution = '" + distributionID + "'", connection);
connection.Open();
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
string name = dr["name"].ToString();
string description = dr["description"].ToString();
string quantity = dr["quantity"].ToString();
SPUFound = new DistributionStandardPackingUnits(name, description, quantity);
}
}
}
return SPUFound;
}
When I run in browser, it just won't show up any retrieved data. When I run in debugging mode, I realized that when it hits the while loop, instead of executing the dr.Read(), it simply just skip the entire while loop and return null values. I wonder what problem has caused this. I tested my query using the test query, it returns me something that I wanted so I think the problem does not lies at the Sql statement.
Thanks in advance.
Edited Portion
public static SqlDataReader executeReader(string query)
{
SqlDataReader result = null;
System.Diagnostics.Debug.WriteLine("FoodBankDB executeReader: " + query);
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
result = command.ExecuteReader();
connection.Close();
return result;
}