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.
Related
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";";
Case: I'm trying execute a query in C# with MySql.Data.MySqlClient, which containts INSERT INTO, i'm getting an error(see below):
Database table:
What im trying to achieve: I want to insert into a new record with: "value_id(Auto Increment)", "machine_id" "tag_name", "int_value", "real_value" and "bool_value";
I have the following code:
*Retrieving machine ID
private void getMachineID()
{
string connStr = "";
string ipAdressID = "'" + machineIP + "'";
string basicQueryID = "SELECT machine_id FROM machine WHERE machine.machine_ip LIKE ";
string totalQueryID = basicQueryID + ipAdressID;
//Create connection
MySqlConnection conn = new MySqlConnection(connStr);
//Query command
MySqlCommand cmd = conn.CreateCommand();
//Assign string to query
cmd.CommandText = totalQueryID;
//Open connection
conn.Open();
//Get result ID from machine where IP adress = machineIP and write to machineID variable.
machineID = (int)(cmd.ExecuteScalar());
}
Code to insert into the record:
try
{
string connStr = "";
MySqlConnection conn = new MySqlConnection(connStr);
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO waardes(machine_id, tag_name, int_value, real_value, bool_value) VALUES(#machineID, #tagName, #intValue, #doubleValue, #boolValue)";
cmd.Parameters.AddWithValue("#tagName", tagName);
cmd.Parameters.AddWithValue("#intValue", intValue);
cmd.Parameters.AddWithValue("#doubleValue", doubleValue);
cmd.Parameters.AddWithValue("#boolValue", boolValue);
cmd.Parameters.AddWithValue("#machineID", machineID);
conn.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Hope you guys can help!
There's no INSERT with where clause.
Take a look at this question: How to insert with where clause
Maybe, you can create an IF inside your app to verify your parameters before executing the INSERT statement.
Based on your query, I believe you need an UPDATE:
UPDATE waardes SET tag_name = #tagName,
int_value = #intValue, real_value = #doubleValue,
bool_value = #boolValue WHERE machine.machine_id LIKE %1%
Is this what you need?
you cannot use where in insert statement, because insert statement is used for adding new rows to table. you better use update statement.
There can be no Where clause used with Insert. However you can use Where when you are using Insert Into. In your statement I suppose you are missing the Select From before your Where clause.
Consider the example:
INSERT INTO tableNameDestination
SELECT feild(s),...
FROM tableNameSource
WHERE Condition
In your case:
INSERT INTO waardes(tag_name, int_value, real_value, bool_value) VALUES(#tagName, #intValue, #doubleValue, #boolValue) Select field1, field2, field3, field4 from machine WHERE machine.machine_id LIKE " + "'" + machineID + "'";
Getting SQLException with this "super useful" exception message (Incorrect syntax near ','.) , was wondering if anyone could see anything wrong with the syntax at a glace?
It is code based off of the example that can be found at http://www.jarloo.com/c-bulk-upsert-to-sql-server-tutorial/
private void importToolStripMenuItem_Click(object sender, EventArgs e)
{
DataTable import = new DataTable();
DialogResult result = this.importFileDialog.ShowDialog();
if (DialogResult.OK == result)
{
Stream importStream = this.importFileDialog.OpenFile();
import.ReadXml(importStream);
importStream.Close();
string tmpTable = "select top 0 * into #import from tblJob;";
using (SqlConnection con = new SqlConnection(CONSTRING))
{
con.Open();
SqlCommand cmd = new SqlCommand(tmpTable, con);
cmd.ExecuteNonQuery();
SqlBulkCopyOptions options = SqlBulkCopyOptions.KeepIdentity;
using (SqlBulkCopy bulk = new SqlBulkCopy(con))
{
bulk.DestinationTableName = "#import";
bulk.WriteToServer(import);
}
//http://www.jarloo.com/c-bulk-upsert-to-sql-server-tutorial/
//Now use the merge command to upsert from the temp table to the production table
string mergeSql = "merge into tblJob as Target " +
"using #import as Source " +
"on " +
"Target.[Location]=Source.[Location]," +
"Target.[Schedule]=Source.[Schedule] " +
"when matched then " +
"update set Target.[Complete]=Source.[Complete]," +
"Target.[Cost]=Source.[Cost]," +
"Target.[Description]=Source.[Description]";
//"when not matched then " +
//"insert (Symbol,Price,Timestamp) values (Source.Symbol,Source.Price,Source.Timestamp)" +
//";";
cmd.CommandText = mergeSql;
cmd.ExecuteNonQuery();
//Clean up the temp table
cmd.CommandText = "drop table #import";
cmd.ExecuteNonQuery();
}
dgvJobs.DataSource = getData("select * from tblJob");
If you want to have multiple Join criteria in your MERGE, you need to use the AND keyword (not a comma ,, as you're using now).
Instead of
merge into tblJob as Target
using #import as Source on Target.[Location]=Source.[Location], Target.[Schedule]=Source.[Schedule]
that you're using, use this instead:
MERGE INTO dbo.tblJob AS Target
USING #import AS Source ON Target.[Location] = Source.[Location]
AND Target.[Schedule] = Source.[Schedule]
This is true for any join condition, also for INNER JOIN and LEFT OUTER JOIN or any other join type, too.
I use the following code for saving.Updating records to Oracle,
OracleConnection con = new OracleConnection(constr);
con.Open();
// Create the command.
OracleCommand cmd = new OracleCommand("", con);
cmd.CommandText = "<?xml version=\"1.0\"?>\n" +
"<ROWSET>\n" +
" <MYROW>\n" +
" <FIELD1>2</FIELD1>\n" +
" <FIELD2>zafar</FIELD2>\n" +
" </MYROW>\n" +
"</ROWSET>\n";
// Set the XML save properties.
KeyColumnsList = new string[1];
KeyColumnsList[0] = "FIELD1";
UpdateColumnsList = new string[1];
UpdateColumnsList[0] = "FIELD2";
cmd.XmlSaveProperties.KeyColumnsList = KeyColumnsList;
cmd.XmlSaveProperties.UpdateColumnsList = UpdateColumnsList;
cmd.XmlSaveProperties.RowTag = "MYROW";
cmd.XmlSaveProperties.Table = "testconn";
cmd.XmlSaveProperties.Xslt = null;
cmd.XmlSaveProperties.XsltParams = null;
rows = cmd.ExecuteNonQuery();
Console.WriteLine("rows: " + rows);
In the Field2 column I want to use select user from dual. I am not able to save current DB user.
The structure of data in the CommandText assumes that all values are literals. There is no way to have it recognize an inner query or expression. If you want to query the user you will have to do it separately and incorporate that into the data. This may be possible with the Xslt and XsltParams clauses.
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#.