Problem with WHERE columnName = Data in MySQL query in C# - c#

I have a C# webservice on a Windows Server that I am interfacing with on a linux server with PHP. The PHP grabs information from the database and then the page offers a "more information" button which then calls the webservice and passes in the name field of the record as a parameter. So i am using a WHERE statement in my query so I only pull the extra fields for that record. I am getting the error:
System.Data.SqlClient.SqlException:Invalid column name '42'
Where 42 is the value from the name field from the database.
my query is
string selectStr = "SELECT name, castNotes, triviaNotes FROM tableName WHERE name =\"" + show + "\"";
I do not know if it is a problem with my query or something is wrong with the database, but here is the rest of my code for reference.
NOTE: this all works perfectly when I grab all of the records, but I only want to grab the record that I ask my webservice for.
public class ktvService : System.Web.Services.WebService {
[WebMethod]
public string moreInfo(string show) {
string connectionStr = "MyConnectionString";
string selectStr = "SELECT name, castNotes, triviaNotes FROM tableName WHERE name =\"" + show + "\"";
SqlConnection conn = new SqlConnection(connectionStr);
SqlDataAdapter da = new SqlDataAdapter(selectStr, conn);
DataSet ds = new DataSet();
da.Fill(ds, "tableName");
DataTable dt = ds.Tables["tableName"];
DataRow theShow = dt.Rows[0];
string response = "Name: " + theShow["name"].ToString() + "Cast: " + theShow["castNotes"].ToString() + " Trivia: " + theShow["triviaNotes"].ToString();
return response;
}
}

Quick solution:
I believe you need single quotes in your selectStr:
string selectStr =
"SELECT name, castNotes, triviaNotes FROM tableName WHERE name = '" + show + "'";
More information:
In .NET, you'll want to be sure you close out any connections explicitly when you no longer need them. The easiest way to do this is to wrap using statements around any types that implement IDisposable, such as SqlConnection in this case:
using(SqlConnection conn = new SqlConnection(connectionStr))
{
SqlDataAdapter da = new SqlDataAdapter(selectStr, conn);
DataSet ds = new DataSet();
da.Fill(ds, "tableName");
DataTable dt = ds.Tables["tableName"];
DataRow theShow = dt.Rows[0];
string response = "Name: " + theShow["name"].ToString() + "Cast: " + theShow["castNotes"].ToString() + " Trivia: " + theShow["triviaNotes"].ToString();
return response;
}
Additionally, it looks like your code could be easily subject to SQL injection. What if someone submits a form with the value: fake name' OR 1=1;DROP DATABASE someDbName;--?
You'll want to take advantage of SQL parameters, something like:
SqlCommand cmd = new SqlCommand(
"SELECT name, castNotes, triviaNotes FROM tableName WHERE name = #show", conn);
cmd.Parameters.AddWithValue("#show", show);

Shouldn't the WHERE clause be WHERE name = '" + show + "'"; Strings should be enclosed in single quotes and not double quotes for SQL statements.
Also the System.Data.SqlClient namespace is for SQL Server and not MySQL. See MySQL official docs for connecting to MySQL via C#.

Related

how to select data from table if table names are in Combo box

I was working on VB.NET and am now switching to C#. I was using the following code to use table as variable from combo box to fill a DataGrid:
Dim strTAB as a String
dtTAB1 = New DataTable
strTAB = cboDTA_TBL.Text
adpPRJ = New SqlDataAdapter("Select * from """ & strTAB & """", conPRJ_NET)
'conPRJ_NET is connection to connect MsSQL Database on server.
adpPRJ.Fill(dtTAB1)
dgFIN_TAB.DataSource = dtTAB1
I am looking for the C# equivalent of """ & strTAB & """.
This code works perfectly in vb.net, no errors.
Can anyone help?
As mentioned, this is a bad design, due to SQL Injection, but here's your answer :
var strTAB = "tableName";
string myString = $"Select * from {strTAB}";
Although, normally you would never concatenate strings to build an Sql statement, you do not need to be concerned about Sql Injection if your combo box DropDownStyle is set to DropDownList. This is essentially "limit to list" but it is NOT the default setting.
The using statements ensure that your database objects are closed and disposed.
I not sure what the the double quotes around the table name are supposed to do but in Sql Server the identifier delimiters are square brackets. ( [ ] )
private void button1_Click(object sender, EventArgs e)
{
string query = "Select * From [" + cboDTA_TBL.Text + "];";
DataTable dtTAB1 = new DataTable();
using (SqlConnection conPRJ_NET = new SqlConnection("Your connection string"))
{
using (SqlDataAdapter adpPRJ = new SqlDataAdapter(query, conPRJ_NET))
{
adpPRJ.Fill(dtTAB1);
}
}
dgFIN_TAB.DataSource = dtTAB1;
}
I use a MySQL command like this:
string db_name= "test";
string db_table = "table";
command.CommandText = "SELECT * FROM " + db_name+ "." + db_table + " WHERE ID = "ID";";
// sometimes you need the: ' around the string-variables
command.CommandText = "SELECT * FROM '" + db_name+ "." + db_table + "' WHERE ID = "ID";";

Syntax error in UPDATE clause

I am trying to update a value in an MS-Access database.
The query works fine when entered directly into Access, but when I try to update it within C#, I get a "Syntax Error in the UPDATE clause" exception.
conMngr.ConnectionStr = ConfigurationManager.ConnectionStrings[_connectionStr].ConnectionString;
conMngr.OpenConnection();
try {
string query = "select Id, counter from tabAppCounter where userId=" + _userId.ToString() + " and appPath = '" + path + "'";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conMngr.DbCon);
DataSet ds = new DataSet();
adapter.Fill(ds);
dataGridView.DataSource = ds.Tables[0];
if (ds.Tables[0].Rows.Count != 0) {
int count = int.Parse(ds.Tables[0].Rows[0].ItemArray[1].ToString())+ 1;
string query2 = "UPDATE tabAppCounter set counter=#count where Id=#Id";
conMngr.OleDbcmd = new OleDbCommand(query2, conMngr.DbCon);
conMngr.OleDbcmd.Parameters.AddWithValue("#Id", ds.Tables[0].Rows[0].ItemArray[0].ToString());
conMngr.OleDbcmd.Parameters.AddWithValue("#count", count.ToString());
conMngr.OleDbcmd.ExecuteNonQuery();
}
} catch (Exception e) {
MessageBox.Show(e.Message + "\n\n" + e.StackTrace);
}
conMngr.CloseConnection();
This code fails after the ExecuteNonQuery with a Syntax error in UPDATE clause exception.
I have tried using a prebuilt query string, but that does not work either.
The access driver (and Ole) do not use named parameters, they are positional based. The order you pass your parameters AND the parameters in your update statement do not match and this will give you an error.
You really should be using ? for the placeholder in the update string.
string query2 = "UPDATE tabAppCounter set counter=? where Id=?";
conMngr.OleDbcmd = new OleDbCommand(query2, conMngr.DbCon);
conMngr.OleDbcmd.Parameters.AddWithValue("#count", count.ToString());
conMngr.OleDbcmd.Parameters.AddWithValue("#Id", ds.Tables[0].Rows[0].ItemArray[0].ToString());
conMngr.OleDbcmd.ExecuteNonQuery();
Finally make sure the types are correct, the passed in type must match the type in the database. So if count is an int in both places then pass count and not count.ToString()
In hopes this is going to be helpful to others: This is what worked for me.
Instead of
string query2 = "UPDATE tabAppCounter set counter=#count where Id=#Id";
I used
string query2 = "UPDATE [tabAppCounter] set [counter]=#count where [Id]=#Id";
and magically, everything started to work correctly.

C# - Select Data from two tables in SQL to Dataset

I have two tables in my database, (Users and Cities) and I want to select all the data in this tables where the column UserID=1 in Users table.
But the Dataset does not find my tables (Users and Cities)
This is my SQL Query:
SELECT * FROM Users INNER JOIN Cities ON Cities.CityID=Users.CityID WHERE Users.UserID=1
And this is the Mathod:
public static DataSet GetData(string SqlQuery)
{
OleDbConnection con = new OleDbConnection(conString);
OleDbCommand cmd = new OleDbCommand(SqlQuery, con);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
Code:
DataSet ds = GetData(myQuery);
string fname = ds.Tables["Users"].Rows[0]["UserFisrtName"].ToString();
string lname = ds.Tables["Users"].Rows[0]["UserLastName"].ToString();
string city = ds.Tables["Cities"].Rows[0]["CityName"].ToString();
string output = "Name: " + fname + " " + lname + " City: " + city;
If you want 2 datatables in the data set, change the sql query to this.
SELECT * FROM Users WHERE Users.UserID=1; select * from City where CityID in (Select cityid from users where userID = 1);
The user table will then be on ds.Tables[0] and the city table on ds.Tables[1].
Please remember to use the using clause to ensure connections, etc are properly disposed.
public static DataSet GetData(string SqlQuery)
{
using(var con = new OleDbConnection(conString))
using(var cmd = new OleDbCommand(SqlQuery, con))
using(var da = new OleDbDataAdapter(cmd))
{
var ds = new DataSet();
da.Fill(ds);
return ds;
}
}
Code:
var ds = GetData(myQuery);
var fname = ds.Tables[0].Rows[0]["UserFisrtName"].ToString();
var lname = ds.Tables[0].Rows[0]["UserLastName"].ToString();
var city = ds.Tables[1].Rows[0]["CityName"].ToString();
var output = "Name: " + fname + " " + lname + " City: " + city;
I found the answer, in the sql query
SELECT * FROM Users, Cities WHERE Users.CityID=Cities.CityID AND Users.UserID=1
You are filling the dataset only with one table, this because the Sql statement only return a one set of data. For access the tables you use indexes, only the columns name will be mapped in the rows of the table so this values can be access by index or by name.
SELECT * FROM Users INNER JOIN Cities ON Cities.CityID=Users.CityID WHERE Users.UserID=1
Also avoid use SELECT * this because you force the database engine to search for the columns of all the tables instead to only use the you already provided, and if you will not use all or someone change te order of it in the table, can be a future problem.
In a Dataset your tables will not automatically have the names of the tables from which they are selected. Use the ordinals instead:
DataSet ds = GetData(myQuery);
string fname = ds.Tables[0].Rows[0]["UserFisrtName"].ToString();
string lname = ds.Tables[0].Rows[0]["UserLastName"].ToString();
string city = ds.Tables[0].Rows[0]["CityName"].ToString();
string output = "Name: " + fname + " " + lname + " City: " + city;

C# and SQLCE Database Not Updating

Ok, I have been having a problem the last few days with my database not updating. I can read the data fine and I'm not getting any exceptions either. I'm trying to update the database then I try to read values again after the update (during same run), and they still hold the original values, so it doesn't seem to be an issue with the database being copied to another folder (I'm using Copy if newer yet neither database is being updated).
Here is the code I'm using. As you can see I tried a few different approaches, none of which worked yet.
public void UpdateDatabaseInStock(string itemName, string tableName)
{
DataSet data = new DataSet("Items");
int val;
//get the file path to the database as a string
string dbfile =
new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName +
"\\Database\\GameData.sdf";
//connect to the database
using (SqlCeConnection cntn = new SqlCeConnection("datasource=" + dbfile))
{
//create an adapter to pull all data from the table
using (SqlCeDataAdapter adpt = new SqlCeDataAdapter
("SELECT * FROM " + tableName + " WHERE Name LIKE '%" + itemName + "%'", cntn))
{
//put the data into a DataSet
adpt.Fill(data);
cntn.Close();
}
//fill the data from the Items table into a DataTable to return.
DataTable itemTable = data.Tables[0];
DataRow a = itemTable.Rows[0];
val = (short)a.ItemArray[3] - 1;
dbfile = "";
data.Dispose();
itemTable.Dispose();
SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = cntn;
cntn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE " + tableName + " SET [In Stock] = #Value WHERE [Name] = '#ItemName'";
//cmd.Parameters.Add("#Value", SqlDbType.SmallInt);
//cmd.Parameters["#Value"].Value = val;
//cmd.Parameters.Add("#ItemName", SqlDbType.NChar, 75);
//cmd.Parameters["#ItemName"].Value = itemName;
cmd.Parameters.AddWithValue("#Value", val);
cmd.Parameters.AddWithValue("#ItemName", itemName);
cmd.ExecuteNonQuery();
//close the conenction
cntn.Close();
cmd.Dispose();
}
}
Any ideas to get it to actually update?
Just a hunch (can't corroborate this on msdn): could it be that using nchar(75) adds spaces to the parameter, thereby causing the WHERE clause to fail?

how to reference columns in sql server connection in C#

I'm trying to translate some perl code into C# and I'm having some trouble with the following.
After establishing a sql server connection and executing the select statement, how do I reference the different elements in the table columns. For example, in Perl it looks like:
my $dbh = DBI -> connect( NAME, USR, PWD )
or die "Failed to connect to database: " . DBI->message;
my $dbname = DB_NAME;
my $dbschema = DB_SCHEMA;
my $sql = qq{select a,b,c,d,e,f,g,h,i,...
from $dbname.$dbschema.package p
join $dbname.$dbschema.package_download pd on p.package_id = pd.package_id
join $dbname.$dbschema.download d on pd.download_id = d.download_id
where p.package_name = '$package'
--and ds.server_address like 'tcp/ip'
order by a,b,c,d,..};
my $sth = $dbh -> prepare( $sql )
or die "Failed to prepare statement: " . $dbh->message;
$sth -> execute()
or die "Failed to execute statement: " . $sth->message;
#now to go through each row in result table
while ( #data = $sth->fetchrow_array() )
{
print "$data[0]";
# If source server FTP is not already open, make new FTP
if ( $data[0] != $src_id )
{
if ( $src_ftp )
{ $src_ftp -> quit; }
$src_ftp = make_ftp( $data[1], $data[2], $data[3], $data[18], $data[19], $data[20] );
$src_id = $data[0];
}
}
so far I've got it down to
string db = NAME;
string myConnectionString = "Data Source=ServerName;" + "Initial Catalog=" + db + "User id=" + ODBC_USR + "Password=" + PWD
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myInsertQuery = "select a,b,c,d,e,f,g,h,i,...
from $dbname.$dbschema.package p
join $dbname.$dbschema.package_download pd on p.package_id = pd.package_id
join $dbname.$dbschema.download d on pd.download_id = d.download_id
where p.package_name = '$package'
--and ds.server_address like 'tcp/ip'
order by a,b,c,d,..";
SqlCommand myCommand = new SqlCommand(myInsertQuery);
myCommand.Connection = myConnection;
myConnection.Open();
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
but how do I reference the columns like data[0] and data[1] in C#. Sorry I'm new to both languages so my background is severely lacking. Thanks!
You could reference your column directly by its column name or by numeric order (it starts with 0 as the first column) either through a DataTable, DataSet, DataReader or a specific DataRow.
For the sake of example i'll use a DataTable here and I will name it as dt and let's say we want to reference the first row then you could reference it with the following Syntax/Format:
dt[RowNumber]["ColumnName or Column Number"].ToString();
For example:
dt[0]["a"].ToString();
Or by number the first column with be 0 like:
dt[0][0].ToString();
And use Parameters by the way because without which it would be susceptible to SQL Injection. Here's a more complete code below:
string db = NAME;
string myConnectionString = "Data Source=ServerName;" + "Initial Catalog=" + db + "User id=" + ODBC_USR + "Password=" + PWD
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
string mySelectQuery = #"SELECT a,b,c,d,e,f,g,h,i,...
FROM package p
JOIN package_download pd on p.package_id = pd.package_id
join download d on pd.download_id = d.download_id
WHERE p.package_name = #PackageName
AND ds.server_address LIKE 'tcp/ip%'
ORDER by a,b,c,d";
try
{
connection.Open();
using (SqlDataAdapter da = new SqlDataAdapter(mySelectQuery, connection))
{
using (SqlCommand cmd = new SqlCommand())
{
da.SelectCommand.Parameters.AddWithValue("#PackageName", txtPackage.Text);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count>0) // Make sure there is something in your DataTable
{
String aVal = dt[0]["a"].ToString();
String bVal = dt[0]["b"].ToString();
// You'll be the one to fill up
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I change your LIKE 'tcp/ip' to LIKE 'tcp/ip%' by the way which is the more appropriate one of using LIKE.
you can use ado.net entity data table to reference the tables in your sql server. I don't know if you're asking exactly this but it may help. because direct referencing to sql server is not possible as far as i know.

Categories

Resources