I'm trying to write into an Access db. The OLE DB connection is stored on the main form (mainFrm). I read and write using the same connection in other parts of my app. For some reason, at this one spot it says I have a syntax error. I have tried writing it different ways but still get the same error message
public OleDbConnection newCon = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\MorganWillis\Documents\PlannerAppData\MainDB.accdb");`
ListViewItem newnote = new ListViewItem(nameTextBox.Text);
newnote.SubItems.Add(DateTime.Today.ToShortDateString());
newnote.SubItems.Add(noteTextBox.Text)`
mainFrm.notesList.Items.Add(newnote);
string tempname = nameTextBox.Text;
DateTime now = DateTime.Today;
string tempnote = noteTextBox.Text;
if(mainFrm.newCon.State == ConnectionState.Closed)
mainFrm.newCon.Open();
OleDbCommand noteCom = new OleDbCommand("INSERT INTO Notes (noteName, noteDate, note)" + "VALUES (?,?,?)", mainFrm.newCon);
noteCom.Parameters.Add("noteName", OleDbType.Char, 50, "noteName").Value = tempname;
noteCom.Parameters.Add("noteDate", OleDbType.DBDate, 8, "noteDate").Value = now.ToShortDateString();
noteCom.Parameters.Add("note", OleDbType.Char, 1000, "note").Value = tempnote;
OleDbDataAdapter noteadapt = new OleDbDataAdapter();
noteadapt.InsertCommand = noteCom;
noteadapt.InsertCommand.ExecuteNonQuery();
mainFrm.newCon.Close();
Close();
You have an errant + in the middle of your query.
It must be eliminated.
Notes was is a key word in access so it wouldn't let me use it for a table name but when I changed the table name it worked just fine Than you everyone for your help!
Related
I have been working on a personal project for the company I work for to control stock levels in order to practice my c#.
I want my application to search through tblJuiceStock, find a matching FlavourID to what the user is inputting and update the stock of that record through an UPDATE SET query.
public void InsertJuiceStockWithCheck()
{
using (OleDbConnection conn = new OleDbConnection())
{
conn.ConnectionString = ConnectionString;
conn.Open();
string tblJuiceStockCheck = "SELECT FlavourID, Quantity FROM tblJuiceStock";
OleDbCommand cmdCheck = new OleDbCommand(tblJuiceStockCheck, conn);
OleDbDataAdapter daCheck = new OleDbDataAdapter(cmdCheck);
DataTable dtCheck = new DataTable();
daCheck.Fill(dtCheck);
foreach (DataRow row in dtCheck.Rows)
{
if ((int)row["FlavourID"] == fID)
{
int currentQty = (int)row["Quantity"];
int updatedQty = currentQty + qty;
string tblJuiceStockExisting = #"UPDATE tblJuiceStock
SET Quantity = #newquantity
WHERE FlavourID = #flavourID";
OleDbCommand cmdJuiceStockExisting = new OleDbCommand(tblJuiceStockExisting, conn);
cmdJuiceStockExisting.Parameters.AddWithValue("#flavourID", fID);
cmdJuiceStockExisting.Parameters.AddWithValue("#newquantity", updatedQty);
cmdJuiceStockExisting.ExecuteNonQuery();
matchFound = true;
break;
}
}
if (!matchFound)
{
string tblJuiceStockNew = "INSERT INTO tblJuiceStock (FlavourID, Quantity, MinStockPOS) VALUES (#fID, #quantity, #minstock)";
OleDbCommand cmdJuiceStockNew = new OleDbCommand(tblJuiceStockNew, conn);
cmdJuiceStockNew.Parameters.AddWithValue("#fID", fID);
cmdJuiceStockNew.Parameters.AddWithValue("#quantity", qty);
cmdJuiceStockNew.Parameters.AddWithValue("#minstock", amt);
cmdJuiceStockNew.ExecuteNonQuery();
}
}
}
Please note: this query works fine in Access when I replace parameters with the same values. Also, using breakpoints I identified that the parameters have the correct values set to them, the variables assigned to them are obtained within another method, all methods are called in the submit button event.
However, the Quantity value in TblJuiceStock remains the same.
My tblJuiceStock table
After some time of messing about the answer was simple.
OLEDB does work with named parameters but you have to declare them, if you don't declare them they use the parameters positioning to match them up.
My problem was that in my query string I had #newquantity first and #flavourID second, whereas when adding my parameters I added #flavourID first and #newquantity second.
i am trying to read excel data to C# using ODBC here is my code
string lstrFileName = "Sheet1";
//string strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq="+path+ ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
string strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=E:\\T1.xlsx;Extensions=xls/xlsx;Persist Security Info=False";
DataTable ds;
using (OdbcConnection oConn = new OdbcConnection(strConnString))
{
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
OdbcDataAdapter oAdap = new OdbcDataAdapter();
oAdap.SelectCommand = oCmd;
ds = new DataTable();
oAdap.Fill(ds);
oAdap.Dispose();
// ds.Dispose();
}
}
my sample data
A
1
2
3
AA
BB
its data table its read 1,2,3 and two blank row
i can understand because of first row its deciding data type , but how can i convert as String and read all row .
Any suggestion .
i Already tried CStr but no help .
For a previous discussion of similar problem here, please check following:
DBNull in non-empty cell when reading Excel file through OleDB
As a workaround, you may also format the column as "text"(i.e. in Excel, select column, right click "Format Cells..."), though this might be impractical if you will process large number of files or if you must not touch the file..
This is partially speculation, but when reading an Excel document as a database, the adapter has to make a judgement on datatypes and usually does a pretty good job. However, because Excel allows mixed datatypes (and databases do not), it occasionally gets it wrong.
My recommendation would to be to not use a data adapter, and just read in every field as an object type. From there, you can easily cast them to strings (StringBuilder, ToString(), etc) or even TryParse into fields you suspect they should be, ignoring the ODBC datatype.
Something like this would be a boilerplate for that:
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
using (OdbcDataReader reader = oCmd.ExecuteReader())
{
object[] fields = new object[reader.FieldCount];
while (reader.Read())
{
reader.GetValues(fields);
// do something with fields
}
}
}
I'm just trying to return a list of columns and their attributes through a system stored procedure. What documentation I have seems to say the below code should work, but I get "Pervasive.Data.SqlClient.Lna.k: [LNA][Pervasive][ODBC Engine Interface]Invalid or missing argument." on the execute. This is PSQL v11, .NET 4.5.
using (PsqlConnection conn = new PsqlConnection(cs))
{
PsqlCommand locationCmd = new PsqlCommand();
PsqlParameter tableParam = new PsqlParameter();
PsqlParameter returnParam = new PsqlParameter();
returnParam.Direction = ParameterDirection.ReturnValue;
locationCmd.CommandText = "psp_columns";
locationCmd.Connection = conn;
locationCmd.CommandType = CommandType.StoredProcedure;
locationCmd.Parameters.Add(tableParam).Value = table;
locationCmd.Parameters.Add(returnParam);
conn.Open();
locationCmd.ExecuteNonQuery();
}
I would think the problem is this line:
locationCmd.Parameters.Add(tableParam).Value = table;
You should set the value before adding the parameter, not afterwards.
tableParam.Value = table;
locationCmd.Parameters.Add(tableParam);
I don't know about Psql but for MSSQL normally you also need to define the parameter name as its found in the stored procedure, or at least that's what I do.
SqlParameter param = new SqlParameter("#tableParam", value);
The psp_Columns system stored procedure is defined as call psp_columns(['database_qualifier'],'table_name', ['column_name']). I know that it says the database qualifier is optional, but I think it's required. You could try passing an empty string for the qualifier. Something like:
using (PsqlConnection conn = new PsqlConnection(cs))
{
PsqlCommand locationCmd = new PsqlCommand();
PsqlParameter dbParam = new PsqlParameter();
PsqlParameter tableParam = new PsqlParameter();
PsqlParameter returnParam = new PsqlParameter();
returnParam.Direction = ParameterDirection.ReturnValue;
locationCmd.CommandText = "psp_columns";
locationCmd.Connection = conn;
locationCmd.CommandType = CommandType.StoredProcedure;
locationCmd.Parameters.Add(dbParam).Value = ""; //might need two single quotes ('')
locationCmd.Parameters.Add(tableParam).Value = table;
locationCmd.Parameters.Add(returnParam);
conn.Open();
locationCmd.ExecuteNonQuery();
}
You should try to get the information of the table SCHEMA using the provided GetSchema method from the Psqlconnection. I have searched a bit on their support site and it seems that this method is supported although I haven't find a direct example using the Tables collection.
This is just an example adapted from a test on mine on SqlServer, I don't have Pervasive install, but you could try if the results are the same
using(PsqlConnection cn = new PsqlConnection("your connection string here"))
{
cn.Open();
string[] selection = new string[] { null, null, table };
DataTable tbl = cn.GetSchema("Columns", selection);
foreach (DataRow row in tbl.Rows)
{
Console.WriteLine(row["COLUMN_NAME"].ToString() + " " +
row["IS_NULLABLE"].ToString() + " " +
row["DATA_TYPE"].ToString()
);
}
}
i was trying to figure this out as well, but with the tables procedure. even though the database and table names are optional, you still have to provide values. for optional parameters, pass in DBNull.Value
this worked for me:
PsqlCommand cm = new PsqlCommand();
cm.CommandText = "psp_tables";
cm.CommandType = CommandType.StoredProcedure;
cm.Connection = new PsqlConnection();
cm.Connection.ConnectionString = <your connection string>;
cm.Parameters.Add(":database_qualifier", DBNull.Value);
cm.Parameters.Add(":table_name", DBNull.Value);
cm.Parameters.Add(":table_type", "User table");
Hi all, please I need your help, I am trying to execute a query and put all the retrieved data in a data set, but I get this error "cannot implicitly convert type 'int' to 'system.data.dataset'"
Here's the code:
// this is a small piece of the sql
String Astra_conn = ConfigurationManager.ConnectionStrings["AstraSeverConnection"].ConnectionString;
System.Text.StringBuilder sql = new System.Text.StringBuilder();
sql.Append(" SELECT ROWNUM AS ID, institution, LPAD (a.zone_name, 3, '0') AS campus, ");
sql.Append(" term_name AS term, student_instance_id AS student_id, subject, course, ");
sql.Append(" section_name AS section_num, offering AS title, ");
//Its OracleConnection because it is an Oracle server otherwise, it would be SqlConnection.
DataSet rs = new DataSet();
OracleConnection Astra_db_Conn = new OracleConnection(Astra_conn);
string myquery = sql.ToString();
OracleCommand cmd = new OracleCommand(myquery);
Astra_db_Conn.Open();
try
{
SqlDataAdapter adpt = new SqlDataAdapter();
rs = cmd.ExecuteNonQuery(); // this is where is get the error.
adpt.Fill(rs);
}
catch(Exception e)
{
log.Error("*** ERROR *** IRISExportQueries.loadStudentInfoLearningSites():" + e);
}
I've also tried
Astra_db_Conn.Open();
try
{
SqlDataReader reader = new SqlDataAdapter();
reader = cmd.ExecuteNonQuery(); // this is where is get the error.
}
catch(Exception e)
{
log.Error("*** ERROR *** IRISExportQueries.loadStudentInfoLearningSites():" + e);</pre>
}
Then I get the error: "cannot implicitly convert type 'int' to 'System.Data.SqlClient.SqlDataReader'"
Thanks your help will be very much appreciated.
The problem is that ExecuteNonQuery returns the number of affected rows (an integer) and not a DataSet or DataReader. I'm afraid you're not using ADO.NET components correctly.
These 2 lines are enough to fill a DataSet
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
adpt.Fill(rs);
In any case this is not your only problem, you're mixing Sql* ADO.NET components with Oracle*ones. Adapter should be OracleDataAdapter
OracleDataAdapter adpt = new OracleDataAdapter(cmd);
adpt.Fill(rs);
Something else: you're never assigning the connection to the command. You should do
OracleCommand cmd = new OracleCommand(myquery, Astra_db_Conn);
And at last but not least important, dispose every instance of classes implementing IDisposable interface, otherwise unmanaged resources as connections to datasase won't be released.
This is the final version applying all my suggestions
var rs = new DataSet();
string myquery = sql.ToString();
using (var Astra_db_Conn = new OracleConnection(Astra_conn))
using (var cmd = new OracleCommand(myquery, Astra_db_Conn))
using (var adpt = new OracleDataAdapter(cmd))
{
Astra_db_Conn.Open();
adpt.Fill(rs);
}
The method ExecuteNonQuery() returns an int with the number of rows that are affected by the command.
To access the data from the query you should see this existing answer: Direct method from SQL command text to DataSet.
SqlDataAdapter adapt= new SqlDataAdapter(cmd.CommandText,cmd.Connection);
adapt.Fill(rs, " Your Table name as it is in database inside this quotation");
now u can give source to ur data views like datalist or datatable or gridview as following
Datalist1.DataSource= rs.Tables("Your Table name as it is in database inside the above q mark")
now atlast jst bind it
Datalist1.DataBind();
I'm using .Net framework 4.0. and I've the the source code like this:
....
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = conn;
String query = "SELECT a.process_id, a.prod_dt, a.vlt_dt, a.prod_month, a.karoseri, a.error_flag, a.created_by, date_format(a.created_dt, '%Y%m%d') as created_dt, a.updated_by, date_format(a.updated_dt, '%Y%m%d') as updated_dt FROM tb_t_vlt_web a " +
"WHERE a.process_id = '" + processId + "'";
DataTable dt = CSTDDBUtil.ExecuteQuery(query);
if (dt.Rows.Count > 0)
{
as400Con = CSTDDBUtil.GetAS400Connection();
as400Con.Open();
using (OdbcCommand as400Cmd = new OdbcCommand())
{
as400Cmd.Connection = as400Con;
as400Cmd.CommandText = "INSERT INTO DCDLIB.TBTVLT(VLPRID, VLPRDT, VLVLDT, VLPRMO, VLKRCD, VLERFG, VLCRBY, VLCRDT, VLCHBY, VLCHDT) VALUES " +
"(?,?,?,?,?,?,?,?,?,?)";
foreach (DataRow dr in dt.Rows)
{
as400Cmd.Parameters.Add("1", OdbcType.VarChar).Value = dr["process_id"].ToString();
as400Cmd.Parameters.Add("2", OdbcType.Numeric).Value = dr["prod_dt"];
as400Cmd.Parameters.Add("3", OdbcType.Numeric).Value = dr["vlt_dt"];
as400Cmd.Parameters.Add("4", OdbcType.VarChar).Value = dr["prod_month"].ToString();
as400Cmd.Parameters.Add("5", OdbcType.VarChar).Value = dr["karoseri"].ToString();
as400Cmd.Parameters.Add("6", OdbcType.VarChar).Value = dr["error_flag"].ToString();
as400Cmd.Parameters.Add("7", OdbcType.VarChar).Value = dr["created_by"].ToString();
as400Cmd.Parameters.Add("8", OdbcType.Numeric).Value = dr["created_dt"];
as400Cmd.Parameters.Add("9", OdbcType.VarChar).Value = dr["updated_by"].ToString();
as400Cmd.Parameters.Add("10", OdbcType.Numeric).Value = dr["updated_dt"];
as400Cmd.ExecuteNonQuery();
as400Cmd.Parameters.Clear();
}
as400Cmd.Dispose();
}
}
... Next Process Below ...
When I execute the program, there is an error occurred on as400Cmd.ExecuteNonQuery();. The error was:
ERROR [00000] [IBM][System i Access ODBC Driver]Column 4: CWB0111 - Input data is too big to fit into field
ERROR [22001] [IBM][System i Access ODBC Driver]Column 4: Character data right truncation.
And then, I've checked the AS400 and there is no problem with the column size.
How can I resolved this error..?
Structure table of TBTVLT
We can't tell what the actual problem is easily because you haven't given us the error message, but the first thing to do is stop doing this:
insertQuery = String.Format("INSERT INTO DCDLIB.TBTVLT(VLPRID, VLPRDT, VLVLDT, VLPRMO, VLKRCD, VLERFG, VLCRBY, VLCRDT, VLCHBY, VLCHDT) VALUES " +
"('{0}',{1},{2},'{3}','{4}','{5}','{6}',{7},'{8}',{9})",
Never build up SQL queries by inserting values into the SQL itself. Instead, you parameterized SQL, and add the parameters to the command.
This will:
Keep your SQL easier to read
Avoid SQL injection attacks
Avoid unnecessary string conversions
I wouldn't be at all surprised if the problem is due to date/time to string conversions.
See the "Using Parameters" MySql documentation for examples.