execute query in dbf from c# - c#

i am doing a program in C# and i´m trying to execute a query in a DBF files that i think is ok but the value of the HasRows property of the DataReader is false. I think the problem is with the dates. This is my code:
string Con = #"Provider=VFPOLEDB.1;Data Source=\\Server\ges_01";
OleDbConnection ConnectionHandler = new OleDbConnection(Con);
ConnectionHandler.Open();
string SQL = "SELECT codalb FROM BALBARA WHERE FECALB BETWEEN CTOD('2015/12/07') AND CTOD('2015/12/13') AND CODCLI LIKE '%9' ORDER BY CODALB"
OleDbCommand Query = new OleDbCommand(SQL, ConnectionHandler);
OleDbDataReader datareader = Query.ExecuteReader();
while(datareader.Read())
{}
I know the rest is ok because if put string SQL="select codalb from balbara"; Works fine.
Any one can say me what i´m doing wrong

The problem here is that the CTOD() function isn't supported by the OLE DB Provider.
Change your query to use DTOS() which:
Returns a character-string date in a yyyymmdd format from a specified
Date or DateTime expression.
So concluding your query might become to:
string SQL = String.Format(
#"SELECT
codalb
FROM
balbara
WHERE
DTOS(fecalb) BETWEEN '{0}' AND '{1}'
AND codcli LIKE '%9'
ORDER BY
codalb",
dateTimeVariable1.ToString("yyyyMMdd"),
dateTimeVariable2.ToString("yyyyMMdd"));
Note 1: check out the indenting to help you write readable code, also I suggest to write all the column/table names lowercase so you can make an easy difference what is your "data" and what is SQL.
Note 2: you can find offical format string examples about the DateTime type here.
EDIT: As a good advice in comments from #AlanB, you should always strive to use parametrized queries instead of a string to prevent SQL Injection attacks.
A remark about the OLEDB parameters:
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.
And about the order of parameters:
Therefore, the order in which OleDbParameter objects are added to the
OleDbParameterCollection must directly correspond to the position of
the question mark placeholder for the parameter in the command text.
So all these informations given your query could look this example:
OleDbCommand Query = new OleDbCommand();
Query.Connection = ConnectionHandler;
Query.CommandText =
#"SELECT
codalb
FROM
balbara
WHERE
DTOS(fecalb) BETWEEN ? AND ?
AND codcli LIKE '%9'
ORDER BY
codalb";
Query.Parameters.Add(dateTimeVariable1.ToString("yyyyMMdd"));
Query.Parameters.Add(dateTimeVariable2.ToString("yyyyMMdd"));
OleDbDataReader datareader = Query.ExecuteReader();

Related

Changing the NLS_DATE_FORMAT in c#

I am trying to change the NLS_DATE_FORMAT of a query and I am struggling to do so.
I have used two approaches
1st
// Use the command to change the format
OracleCommand cmd = new OracleCommand("ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'", conn);
cmd.ExecuteNonQuery();
// Then do another command
OracleCommand mainCommand = new OracleCommand("SELECT * FROM dates_table", conn);
OracleDataReader reader = command.ExecuteReader();
while(reader.Read())
{
// Read Data
}
This option's queries both succeed, yet the date format still contains the time (HH:MM:SS)
2nd
// Put both commands in the same sql statement
string sql = "ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\';";
sql += "SELECT * FROM dates_table";
OracleCommand command = new OracleCommand(sql, conn);
OracleDataReader reader = command.ExecuteReader();
while(reader.Read())
{
// Read Data
}
This option does not succeed and gives me the error ORA-0091 which seems to be the semicolon in the first statement. I have also tried removing the semicolon, yet it produces a ORA-00922 error.
I am a bit stuck as of now, any help would be greatly appreciated. Thanks in advance!
An oracle DATE is a binary data type and does NOT store a format so when you get the date column in a 3rd-party application (i.e. C#) you will only get the binary data representing years, months, days, hours, minutes and seconds and not any format.
The NLS_DATE_FORMAT session parameter is the internal format Oracle will use in the user's session to implicitly cast dates to (and from) strings.
The SQL/Plus and SQL Developer client applications also use the NLS_DATE_FORMAT session parameter to control how the binary date values are displayed to the user but this formatting is done on the client application (and not by the Oracle database).
If you want to format a DATE data type then do the formatting in C#.
If you really want to format it in the database then use TO_CHAR to convert each date column (without a format) to a formatted string.
SELECT TO_CHAR(date_column, 'YYYY-MM-DD') AS formatted_date_column
FROM dates_table

Return numerous SQL results to C# array

I have seen a few questions asked about this kind of thing already, but whenever I try anything it just doesn't work with this exact instance. I have a remote SQL SERVER database set up, and it has over 2000 rows.
This is my C#:
command.Connection = connectionString;
command.CommandType = CommandType.Text;
command.CommandText = "SELECT IconUrl FROM Items WHERE DefIndex IN " + iconSqlString;
connection.Open();
string iconString = command.ExecuteScalar().ToString();
connection.Close();
I do have the SqlConnection set up and all that, I just don't think it is necessary to be included.
iconSqlString is in the format of (32, 126, 68). The string has over 150 items and is different each time. I need to return the IconUrl for all items in the string. The current query for some reason only returns on IconUrl, for the item with the value of 35 in the 51st position (out of 196). I know that the iconString is in the format of a string, but it is only for testing purposes, I was expecting it to have returned all the results, separated by commas or something else. I wish to return all the values possible to an array, to be called later with something like sqlItem[5]. How would I do this?
ExecuteScalar is for single result, you will need to use ExecuteReader instead.
Also as a side note, you should never use variables to perform a query because of an attack called SQLI or SQL Injection. Here is a link with some examples on how to execute parameterized queries.

How to insert ONLY the date (time not included) to ms access database using C#

OleDbCommand command3 = new OleDbCommand();
command3.Connection = connection;
command3.CommandText = "INSERT into AddLoad(ID_Number,Load_Added,Load_Date) values (#ID_Number, #Load_Added,#Load_Date)";
command3.Parameters.AddWithValue("#ID_Number",UserControl_AddLoadConfirmation.INumberValue);
command3.Parameters.AddWithValue("#Load_Added",addbalance);
command3.Parameters.AddWithValue("#Load_Date",DateTime.Now.ToString());
command3.ExecuteNonQuery();
I tried changing the format of my date column (Load_Date) in ms access database to "Short Date" format, when I view all datas to my Datagrid, it still comes with the hour:minute format.
im not sure with the problem maybe it's this code DateTime.Now.ToString()?
If you are going to persist a date or datetime in your database
the type in your database should be datetime (not varchar!)
You should pass DateTime types to your database directly in the command (not a string equivalent)
You should read back a datetime type when querying from the database (not a string equivalent)
So this line
command3.Parameters.AddWithValue("#Load_Date",DateTime.Now.ToString());
Becomes this
command3.Parameters.Add(New OleDbParameter("#Load_Date", OleDbType.Date) { Value = DateTime.Today });
This also ensures that you are passing the correct type to the command so it knows how it is represented in the schema. You really should not call AddWithValue as this does not pass that information in to the command.
Also keep in mind that when working with Ole (ie. access) parameters are positional and not named. That means the order they appear in in the query has to be the same order they appear in within the parameter collection.

What is the better way of making an SQL statement in Visual Studio?

I was looking up how to insert into my database via sql and I noticed the way I had seen a person do an sql statement was different from the way I had done it and and now I'm wondering which way is better.
An example of what I had done in a previous (select) statement.
SqlConnection conn = new SqlConnection(Variables.Default.sqlConString);
conn.Open();
string builtCmd = Variables.Default.returnUserNameSql1 + usersInput + Variables.Default.returnUsernameSql2;
SqlCommand cmd = new SqlCommand(builtCmd, conn);
usersInput is a string.
Variables.Default.returnUserNameSql1 = SELECT [Username] from [dbo].[LoginDetails] WHERE [Username] = '
returnUsernameSql2 = '
What I have seen online (not my query):
cmd.CommandText = "INSERT INTO klant(klant_id,naam,voornaam) VALUES(#param1,#param2,#param3)";
cmd.Parameters.Add(new SqlParameter("#param1", klantId));
cmd.Parameters.Add(new SqlParameter("#param2", klantNaam));
cmd.Parameters.Add(new SqlParameter("#param3", klantVoornaam));
Is the use of the Parameters function (?) better? If so in what way?
Thanks for your time.
I modified my original query thanks to the help of some of the comments here. I'll post it if anyone's interested:
using (SqlConnection conn = new SqlConnection(Variables.Default.sqlConString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(Variables.Default.returnUserNameSql, conn))
{
cmd.Parameters.Add(new SqlParameter(Variables.Default.param1, usersInput));
SqlDataReader reader = cmd.ExecuteReader();
usernameTaken = reader.Read();
cmd.Dispose();
}
conn.Close();
}
Look up "SQL Injection attack" on google. Bobby Tables says hello. And then realize that your way is not bad, it is a security nightmare because everyone with access to your program can execute whatever SQL he wants.
SQL Injection is certainly an important reason not to use string concatenation, but there are a few others:
string delimiters - you'd need to include string delimiters in your SQL statement, and if the values you concatenate include them as well, you'll likely get syntax errors. With parameters you don't need string delimiters, and values with apostro[phes or quotes don't affect the SQL syntax.
string conversion of values - you'd need to convert all non-string values (numbers, dates, etc.) to strings, and ensure that their string represenatations are exactly reversible by the server. This is especially problematic for dates since the same string can represent two different dates depending on the culture of the server. With parameters, the values are passed without translation, so there's no risk that the server misinterprets values.
pre-compilation - with concatenation, the server must reanalyze each query to determine the "best" plan. With parameters, the server can re-use a cached plan since the actual query has been issued before, just with different parameters. This doesn't mean that queries will always perform faster, and in some cases can actually cause bad plans to be used, but it is a consideration if you issue millions of queries that only differ in parameter values.

System.Data.Sqlite FormatException using a parameter with LIKE

I'm using Sqlite as my database of choice in a C# forms app, with http://sqlite.phxsoftware.com/ System.Data.SQLite provider. I'm trying to implement a search function, but it's not playing nice... or I'm missing something.
The simplified sql I'm using looks like this:
SELECT *
FROM Table
WHERE column LIKE #boundParameter ESCAPE '!'
When I run this, in any permutation with a parameter (using ? or ?001 or :boundParameter or #boundParameter), it gives me a FormatException: "Input string was not in a correct format." I haven't been able to find anything that says I can't use parameters with LIKE. Anyone know something about this? Do I need to do it some other way?
I would recommend trying something like this:
"SELECT * FROM [Table] WHERE [column] LIKE #boundParameter ESCAPE #escape";
and then:
command.Parameters.AddWithValue("#boundParameter", parameter));
command.Parameters.AddWithValue("#escape", "!");
Parameters.AddWithValue is the SQLite way of adding a bound parameter, rather than having to declare a new one each time.
#Noah (sorry, can't comment yet)
Stephen Jennings is right, you don't have to quote the value you are binding.
How do you connect and add parameters?
I haven't been using SQLite much, but the following should work;
SQLiteCommand command = _yourConnection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = "SELECT * FROM Table WHERE column LIKE #boundParameter";
command.Parameters.Add(new SQLiteParameter("#boundParameter", _yourSearchCriteria));
...
"Input string was not in a correct format" is not an error message returned by any version of SQLite
It must be being returned by the wrapper. SO ... I am going to guess that you are using the ADO.NET 2.0 Provider from sqlite.phxsoftware.com
You must remember to quote the value you are binding to the parameter.
For example, if you use
command.Parameters.Add(new SQLiteParameter("#boundParameter", _pattern));
then _pattern = "'test'" and not "test"
This program-code executes a query, that includes PARAMETER SUBSTITUTION and PATTERN FITTING in one step. Here, the string variable myNamePattern is the string that we wanna find the customers for, so that all returned customers will INCLUDE THE variable myNameattern string. I had the same problem, but i solved it! This is the perfect way, to substitute a string pattern (that is also a parameter) into SQLiteCommand.CommandText:
SQLiteCommand command = conn.CreateCommand();
command.CommandText = "select * from Customer where name like #myStringParameter";
command.Parameters.Add("myStringParameter", System.Data.DbType.String).Value = "%"+ myNamePattern+ "%";

Categories