C# problem querying dbase file; problem using WHERE clause - c#

I'm querying a dbase .dbf file with odbc from within my c# code and am having a problem using a 'where' clause in my query. I can retrieve and read the records fine if I just 'select * from FILE.DBF', and every example I see on web pages as I search for an answer show just that much syntax. I've tried multiple ways of constructing the select statement with a 'where' and so far they all fail. So, I'm wondering whether I just can NOT use a 'where' clause in a query against a dbase file, or whether I simply haven't hit on the correct syntax yet.
I've tried:
select * from FILE.DBF where GROUP = 21;
select * from FILE.DBF where GROUP = '21';
select * from FILE.DBF where GROUP = "21";
The result of all of these is the error: ERROR [42000] [Microsoft][ODBC dBase Driver] Syntax error in WHERE clause.
Any help will be appreciated.

Try surrounding the word GROUP with brackets ... as in ..
select * from FILE.DBF where [GROUP] = 21;
GROUP is a SQL keyword and it's most likely causing some issues.

GROUP is a keyword used for SQL itself. Try running the same query but with a different 'where' clause, by substituting 'Group' with another field instead (and a different condition too, naturally). If the query works, then 'GROUP' is being mixed up with the SQL syntax for GROUP BY, and thus you might need to use brackets or some other character to enclose the field name.

Related

c# “Syntax Error in From Clause” with Access

I'm getting “Syntax Error in From Clause” when using
the simple query SELECT * FROM Order.
The weird thing is that I use this query many times during my project.
I'm using SELECT * FROM Suppliers and it works just fine, all the tables are connected to the same Access file.
order is an sql keyword, use with brackets:
SELECT * FROM [Order]
Order is a reserve word and thus needs escaping like
SELECT * FROM "Order"
(OR)
SELECT * FROM [Order]
Better, never name a DB object with reserve word or keyword. If you really have to then try like tblOrder

LINQ to SQL will not generate sargable query

I'm using LINQ To Sql (not Entity Framework), the System.Data.Linq.DataContext library, hitting a SQL Server 2005 database and using .Net Framework 4.
The table dbo.Dogs has a column "Active" of type CHAR(1) NULL. If I was writing straight SQL the query would be:
SELECT * FROM dbo.Dogs where Active = 'A';
The LINQ query is this:
from d in myDataContext.Dogs where d.Active == 'A' select d;
The SQL that gets generated from the above LINQ query converts the Active field to UNICODE. This means I cannot use the index on the dbo.Dogs.Active column, slowing the query significantly:
SELECT [t0].Name, [t0].Active
FROM [dbo].[Dog] AS [t0]
WHERE UNICODE([t0].[Active]) = #p1
Is there anything I can do to stop Linq to Sql from inserting that UNICODE() call (and thus losing the benefit of my index on dogs.Active)? I tried wrapping the parameters using the EntityFunctions.AsNonUnicode() method, but that did no good (it inserted a CONVERT() to NVARCHAR instead of UNICODE() in the generated sql), eg:
...where d.Active.ToString() == EntityFunctions.AsNonUnicode('A'.ToString());
Linq is meant to make it easier to write queries and does not always generate optimal SQL. Sometimes when high performance is required it is more efficient to write raw SQL directly against the database, the Linq datacontext supports mapping of SQL result to entities just like linq.
In your case I would suggest writing:
IEnumerable<Dog> results = db.ExecuteQuery<Dog>(
"SELECT * FROM dbo.Dogs where Active = {0}",
'A');
This is an old question, but I bumped into this recently.
Instead of writing
from d in myDataContext.Dogs where d.Active == 'A' select d;
Write
from d in myDataContext.Dogs where d.Active.Equals('A') select d;
This will produce the desired SQL without having to resort to any of the "hacks" mentioned in other answers. I can't say why for certain.
I've posted that as a question, so we'll see if we get any good answers.
There's not much you can do to the way LINQ queries are translated into SQL statements, but you can write a stored procedure that contains your queries and call that SP as a LINQ2SQL function. This way you should get full benefit of SQL Server optimizaions
You can do a little hack (as it is often required with LINQ to SQL and EF). Declare the property as NCHAR in the dbml. I hope that will remove the need to do the UNICODE conversion. We are tricking L2S in a benign way with that.
Maybe you need to also insert the EntityFunctions.AsNonUnicode call to make the right hand side a non-unicode type.
You can also try mapping the column as varchar.

Using query expressions for Unicode strings with LINQ

I am working with LINQ and and I have a database with columns for storing local content(non-english characters). Now I want to make a query using linq as follows
var desc = from p in db.GetDesc
where p.Category.Contains("xxxx".ToString())
orderby p.Date descending
select p;
Here the Category column contains unicode strings and the above query string doesn't work. How can I use natural language queries with LINQ?
Unicode in general should work fine with Linq to SQL and Linq to Entities against SQL Server (which I assume you're using). In fact your query should be
var desc = from p in db.GetDesc
where p.Category.Contains("xxxx")
orderby p.Date descending
select p;
There's no need to use .ToString(), since "xxxx" is already a Unicode string.
The problem seems to be with SQL Server. I tried your query against a table containing your Ethiopian characters, and as you say it doesn't work. If I query for .Contains("ስፖርት") then all rows are returned.
Running the SQL directly has the same result.
Trying a simple query like this fails (returns all rows)
select * from TestTable where Title like N'%' + NCHAR(0x1275) + N'%'
Here 0x1275 is the Unicode code point of the ት character.
If we look at the SQL documentation for NCHAR we see that only Unicode code points upto 4000 are supported. Unfortunately 0x1275 = 4725 so it looks like SQL Server (even 2012) won't support Ethiopian characters.
Having read that 4000 is the limit, testing reveals that running the above simple query with NCHAR(3129) succeeds (in my case returns no rows), but >= 3130 fails (returns all rows).

SQL Server: way to see final query with filled parameters

Is there a way to see final query which is passed to SQL Server database from my C# app ?
For ex I got query:
SELECT * FROM mytable WHERE x = #yyyy;
This creates and SQLCommand object
SqlCommand cmd = new SqlCommand("SELECT * FROM mytable WHERE x = #yyyy");
Plus I need to pass parameter:
cmd.Parameters.Add("#yyyy","MyValue");
What I want to see (in debug in C# or somewhere in SQL Server Management Studio) is this:
SELECT * FROM mytable WHERE x = MyValue
Where can I find such query ?!
Best regards
Where can I find such query ?!
You can't. Such a query never exists. The values are not substituted into the SQL.
I think actually sp_executesql is called, and this function accepts the parameters separately from the SQL. You can check this using SQL Profiler to see the actual SQL.
Update:
ORDER BY #descOrAsc
Your problem is that parameters can only be used in certain places where expressions are allowed. DESC is not an expression - it is a reserved word. You cannot use a parameter containing the string "DESC" instead of writing the keyword DESC in the query.
Also, you haven't specified which column to order by.
You can run the SQL Server Profiler and see all the queries that get executed, to see whats happening (and copy paste these into the Sql Server Management Studio to do tests etc)
I would expect the query to be passed to SQL Server with the parameters. There should be no need for anything to ever create a full SQL-only query. It makes no sense to do so, as it just means more conversions for either the client, the server or both. On the server side, the query processor is going to want to parse the query into clauses with values - if the command can pass those values directly, where's the advantage on converting them into the SQL statement, only to have the server parse them into separate values again?
1.You can use SQL Profiler. (here you can see all process)
2.You can write all your queries to SQL Server table. And then you can always get queries from this table.

C# OleDb select query throws missing operator exception

I'm currently connecting to and working with a MS Access database. I can do a generic select * query fine, so I am connected to the db, but when I try to select using parameters it throws a missing operator exception.
string selectStatement = "Select ID from pages where page_title = ? limit 1";
string title = Request.QueryString["pagetitle"];
OleDbCommand selectCommand = new OleDbCommand(selectStatement, conn);
selectCommand.Parameters.Add("#p1",OleDbType.VarChar);
selectCommand.Parameters["#p1"].Value = System.Web.HttpUtility.UrlDecode(title);
OleDbDataReader selectResult = selectCommand.ExecuteReader();
The error I get is on the ExecuteReader line:
Exception Details: System.Data.OleDb.OleDbException: Syntax error (missing operator) in query expression 'page_title = ? limit 1'.
I've tried using #p1 inside the query, as well as the current ?. I've tried adding the parameters different ways, including removing the # in the parameter name. Nothing seems to work. Can someone point me in the right direction?
AFAIK, there is no LIMIT clause in MS Access.
And, parameters should be named, #p1 in your case, instead of ?
I haven't worked with Access for years, so I might be wrong, but instead of LIMIT, try this:
Select TOP 1 ID from pages where page_title = #p1
Also, if appropriate, consider this advice:
MS Access isn't quite the right DBMS to handle websites (I suspect in your case it's a website). For an alternative file-based database management systems, check SQLite and FirebirdSQL. Both have a lot of tools you can use for GUI, like SQLite Maestro, and respectively IBExpert.
Queries are more flexible in those DBMS.

Categories

Resources