Why aren't my parameterized variables being added to my Sql query?
I have two parametrized variables set by combobox.text which is selected by the end user.
I get the error below when trying to use a query that uses a parameterized variable.
Additional information: Must declare the scalar variable "#username"
Am I missing something?
Example Query
SQL = "SELECT stationID, LocationName, plandate, username, status FROM dbo.joblist WHERE username = #username and status = #status";
Code Snippet
//Decide what query
String SQL = SQLSelection();
//Connection String
String ConnString = "Data Source=dbsqlexpress; Provider=SQLOLEDB; Initial Catalog=Data; User ID=mobile; Password=PW";
//Create and initalize Oledbconnection object and pass connection string into it.
OleDbConnection con = new OleDbConnection(ConnString);
//open connection to database
con.Open();
//create adapter that sits inbetween dataset and datbase
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = new OleDbCommand(SQL,con);
adapter.SelectCommand.Parameters.Add("#username", OleDbType.VarChar).Value = auditorCmb.Text;
adapter.SelectCommand.Parameters.Add("#status", OleDbType.VarChar).Value = statusCmb.Text;
//Create dataset
DataSet dataset = new DataSet();
using (DataTable dt = new DataTable())
{
adapter.Fill(dt);
dataGridView1.AutoResizeColumns();
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
con.Close();
dataGridView1.DataSource = dt;
int rowCount = rowCount = dt.Rows.Count;
label10.Text = rowCount.ToString("n0");
}
}
With OLE DB (and ODBC), you need to specify ? as parameter markers in the SQL statement. These are then mapped by ordinal according to the order parameters were mapped to the collection.
SQL = "SELECT stationID, LocationName, plandate, username, status FROM dbo.joblist WHERE username = ? and status = ?;";
Avoid using OLE DB and ODBC in .NET applications. The .Net Provider for SQL Server (a.k.a SqlClient) will provide better performance from .Net Applications. Also, Microsoft has announced deprecation of OLE DB for relational database access in SQL Server.
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
MSDN:OleDbCommand.Parameters Property
Related
After I try to output the password in the dataGrid, from the given Username in the txt_Username textbox, I get this error message:
MySql.Data.MySqlClient.MySqlException: "Unknown column 'Test' in 'where clause'"
MySqlDataAdapter da = new MySqlDataAdapter("Select Password from tbl_anmeldedaten Where Username=" + txt_Username.Text, con);
da.SelectCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
The exact cause of the error is that you are trying to execute the following query:
SELECT Password
FROM tbl_anmeldedaten
WHERE Username = Test;
Does it look like Test should have single quotes around it? Yes, it should, and you could add that to your raw query. But, concatenating a query like this in C# leaves open the possibility for SQL injection. A much better approach is to use prepared statements:
string sql = "SELECT Password FROM tbl_anmeldedaten WHERE Username = #val1";
MySqlCommand cmd = new MySqlCommand(sql, MySqlConn.conn);
cmd.Parameters.AddWithValue("#val1", txt_Username.Text);
cmd.Prepare();
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// consume a record in the result set
}
You are using string concatenation which is a vector for SQL injection attacks. Perhaps the username in the text field is doing some SQL which it shouldn't be allowed to (for instance '' OR Test=1. There are plenty of resources on using parameterized queries which should remedy the problem.
I tried to get table which has top record from Oracle database through ODBC driver. For this, I am using below code.
OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();
builder.ConnectionString = "Driver={Oracle in OraClient11g_home1};Dbq=localhost;Uid=system;Pwd=abc;Database = NORTHWIND";
OdbcConnection con = new OdbcConnection();
con.ConnectionString = builder.ConnectionString;
con.Open();
string query = "SELECT \"NORTHWIND\".\"ORDERS\".\"ID\" AS \"My field id\" FROM \"NORTHWIND\".\"ORDERS\" WHERE ROWNUM = 1";
OdbcCommand cmd = new OdbcCommand(query,con);
var k = cmd.ExecuteReader();
var datatable = new DataTable();
datatable.Load(k);
con.Close();
The above code is working fine for me. I need to execute query without database name. Here database name is NORTHWIND. But If I am using query without database name like "SELECT \"ORDERS\".\"ID\" AS \"My field id\" FROM \"ORDERS\" WHERE ROWNUM = 1"
I got an exception "table or view does not exist."
Even if my connectionstring has database name, I got this exception.
Can anyone explain me why I got the above exception when using query without database name?
Change your connection string to this-
builder.ConnectionString = "Driver={Oracle in OraClient11g_home1};Dbq=localhost;Uid=system;Pwd=abc;Data Source = NORTHWIND;";
Referrences-
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.initialcatalog(v=vs.110).aspx
http://www.c-sharpcorner.com/UploadFile/nipuntomar/connection-strings-for-oracle/
https://docs.oracle.com/database/121/ODPNT/featConnecting.htm#ODPNT199
I am using an Informix db, and I am trying to get data for a specific item and store it in a datatable.
I checked the following:
1) connection string looks good
2) the connection is able to open
3) I used the same connection string from the web.config on a dataset creating a table adapter and it is able to retrieve the record.
This is the code I am using:
var connectionstring = ConfigurationManager.ConnectionStrings["TestDataTable"].ConnectionString;
OdbcConnection con = new OdbcConnection(connectionstring);
//con.ConnectionString = connectionstring;
if (TxtItem.Text != hold_item)
{
con.Open();
OdbcCommand cmd = new OdbcCommand(#"Select t_item,t_idsc,t_upct,
t_item_upc,t_ctyp,t_citg,
t_best,t_disp,t_mold,t_csel
from informix.tsckcm907
where t_item = " + stitem, con);
OdbcDataReader myReader = cmd.ExecuteReader();
DataTable testdt = new DataTable();
testdt.Load(myReader);
foreach (DataRow row in testdt.Rows)
{
lbldesc.Text = row["t_idsc"].ToString();
Spanish_Item();
{
DropDownList2.SelectedIndex = 1;
object stlanguage = 1;
hold_language = Convert.ToString(stlanguage);
TxtBestBefore.Text = row["t_best"].ToString();
holdbest = Convert.ToInt16(TxtBestBefore.Text);
}
}
myReader.Close();
myReader.Dispose();
cmd.Dispose();
con.Close();
con.Dispose();
}
in debug mode my error occurs at the OdbcDataReader line:
error message:
An exception of type 'System.Data.Odbc.OdbcException'
occurred in System.Data.dll but was not handled in user code
Additional information: ERROR [42000] [Informix]
[Informix ODBC Driver][Informix]A syntax error has
occurred.
If your Informix ODBC driver says: "A syntax error has occurred" then you have to check your SQL statement:
"Select t_item,... from informix.tsckcm907 where t_item = " + stitem
I think that something is wrong with stitem. We don't know what type and value it is, but if its type is some kind of string or date then it may be in the wrong form. Easiest way is to extract full SQL statement (simply print it before execution) and use it with some database editor (for example db_access from Informix). Then make it work in SQL editor and transform stitem variable into acceptable form (add quotes, escape internal quotes, escape special characters etc.)
I also recommend use of PreparedStatement that separates your query from data. This way you do not need to worry about stitem form. No quotes, no escaping, just place holder in query string and value added separately.
I don't use C# but I see that C# can work with preapred statements with unnamed parameters:
cmd.CommandText = "SELECT ... FROM ... WHERE t_item = ?";
cmd.Parameters.Add("#t_item", ObdcType.VarChar, 200).Value = t_item;
or with named parameters:
cmd.CommandText = "SELECT ... FROM ... WHERE t_item = #t_item";
cmd.Parameters.Add("#t_item", ObdcType.VarChar, 200).Value = t_item;
I use unnamed parameters from ODBC so Informix driver can work with such parameters but you will have to check it yourself with C#.
I need a solution to transfer all data from SQL Server CE to Access mdb database.
I tried this approach http://www.codeproject.com/Answers/483989/HowplustoplusExportplusSQLplusTablesplusToplusAcce#answer2 (solution # 2) but getting an error "No database specified in connection string or IN clause."
The code works if I connect to non-compact SQL server.
I guess the problem is with connection string in IN clause but I cannot figure out how to change it.
Here is my code:
private void ExportTable(string tableName, string source, string destination)
{
var connStr = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", destination);
var cmdText = string.Format("SELECT * INTO {0} FROM [{0}] IN ''[Data Source={1};Max Database Size='4000';Persist Security Info=False;];", tableName, source);
using (var conn = new OleDbConnection(connStr))
{
conn.Open();
using (var cmd = new OleDbCommand(cmdText, conn))
{
cmd.ExecuteNonQuery(); // error on this line
}
conn.Close();
}
}
The connection string: Data Source={1};Max Database Size='4000';Persist Security Info=False; working ok when I connect to the database directly.
UPDATE: Apparently the format of the source DB in IN Clause should be as following:
[type; DATABASE = path]
(see: http://answers.microsoft.com/en-us/office/forum/office_2010-access/access-2010-runtime-error-3170-could-not-find/0b085797-618a-488f-b1b4-30af00f04b3f)
When I use
var cmdText = string.Format("SELECT * INTO {0} FROM [{0}] IN ''[SqlServer CE; DATABASE={1}];", tableName, source);
I am getting different error: Could not find installable ISAM.
Do you know correct type for SQLServer CE? Is it supported at all? I could not find any info about it.
I have also tried: SQL CE, SQLSERVER.CE, Microsoft.SQLSERVER.CE.OLEDB.3.5, Microsoft.SQLSERVER.MOBILE.OLEDB.3.0 etc. - Same error...
I think the stumbling block here is that the trick you are trying to use requires an ODBC connection to the SQL Server and as far as I know there is no ODBC driver for SQL Server Compact. I'm pretty sure that the syntax [ODBC;Driver=...] in Access has no OLEDB equivalent, so the trick won't work with SQL Server Compact. (As you discovered, it does work with "real" SQL Server because ODBC connections are supported for that platform.)
I was curious to see what I could accomplish in C# using an OLEDB connection to the SQL Server Compact database (which is supported, as #MrZak pointed out in his comment). I came up with the following. It pulls the SQL table into a DataTable, sets the status of each row to "Added", and then updates (inserts into) the corresponding table in Access.
string myConnectionStringMDB =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data Source=C:\Users\Gord\Desktop\fromCE.mdb;";
string myConnectionStringSQL =
"Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;" +
#"Data Source=C:\Users\Public\test\myData.sdf;";
using (OleDbConnection conSQL = new OleDbConnection(),
conMDB = new OleDbConnection())
{
conSQL.ConnectionString = myConnectionStringSQL;
conSQL.Open();
conMDB.ConnectionString = myConnectionStringMDB;
conMDB.Open();
using (OleDbCommand cmdSQL = new OleDbCommand(),
cmdMDB = new OleDbCommand())
{
cmdSQL.CommandType = System.Data.CommandType.Text;
cmdSQL.Connection = conSQL;
cmdSQL.CommandText = "SELECT * FROM [Table1]";
var daSQL = new System.Data.OleDb.OleDbDataAdapter(cmdSQL);
var dt = new System.Data.DataTable();
daSQL.Fill(dt);
foreach (System.Data.DataRow dr in dt.Rows)
{
// change row status from "Unchanged" to "Added" so .Update below will insert them
dr.SetAdded();
}
cmdMDB.CommandType = System.Data.CommandType.Text;
cmdMDB.Connection = conMDB;
cmdMDB.CommandText = "SELECT * FROM [Table1]";
var daMDB = new System.Data.OleDb.OleDbDataAdapter(cmdMDB);
var cbuilderMDB = new OleDbCommandBuilder(daMDB);
cbuilderMDB.QuotePrefix = "[";
cbuilderMDB.QuoteSuffix = "]";
daMDB.Update(dt);
}
conSQL.Close();
conMDB.Close();
}
I'm still new to this, but "private void" from what I understand cant be imported or exported. Its only readable in that class or as a executable.
I connected an sql database in c# and now trying to put the contents into a dataset. How will I be able to do that?
My code is:
string constr = "Data Source=ECEE;Initial Catalog=Internet_Bankaciligi;User ID=sa";
SqlConnection conn = new SqlConnection(constr);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from Internet_Bankaciligi", conn);
DataSet myDataSet = new DataSet();
DataRow myDataRow;
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
mySqlDataAdapter.Fill(myDataSet,"Internet_Bankaciligi");
myDataRow = myDataSet.Tables["IB_Account"].NewRow();
myDataRow["Account_ID"] = "NewID";
myDataRow["Branch_ID"] = "New Branch";
myDataRow["Amount"] = "New Amount";
myDataSet.Tables["Customers"].Rows.Add(myDataRow);
the line: "mySqlDataAdapter.Fill(myDataSet,"Internet_Bankaciligi");" gives an error as 'Invalid object name 'Internet_Bankaciligi'.' but Internet_Bankaciligi is my database name.
Also if i use:
SqlCommand selectCMD = new SqlCommand("select (*) from IB_Account", conn);
SqlDataAdapter myAdapter = new SqlDataAdapter();
myAdapter.SelectCommand = selectCMD;
myAdapter.Fill(myDataSet);
then: "SqlCommand selectCMD = new SqlCommand("select (*) from IB_Account", conn);" gives an error saying invalid syntax. How will I get it correct?
If "Internet_Bankaciligi" is your actual database name, then you can't execute a SQL command directly against it. You have to change your SQL to select from a table or a view.
Your second example doesn't work because "SELECT (*)" is not valid syntax. It should be "SELECT * FROM IB_Account"... no parentheses.
I checked this statement in Sql Server 2008:
Select (*) from <table>
It doesn't work. I never seen this syntax, not in sqlserver 2005, nor Oracle nor sqlite.
try this one:
Select * from <table>
Edit: If I were you I will try using strongly typed datasets, or even Entity Framework which both are more advance and easier to work with. Google them.