Problem with Insert query to Paradox table using C# - c#

I have Paradox 5.x tables I need to connect to in order to select and update.
I am using OLEDBConnection.
selecting from the tables I have no problem.
while trying to insert into the tables I met a problem when I entered hardcoded the fields names I got an error:
The INSERT INTO statement contains the following unknown field name: ...
so I used OleDbDataReader.GetName(...) to get fields names.
now I use the fields names received from table in order to insert into table and I still get the same error.
I think the problem is with the field name: 'Truck #1 Serial Number'
Table name: 'Vehicles'
I tried using [], ."", .[] and
.[""].
I have read about the need of Borland engine but I'm not sure this is the issue.
Thanks upfront.
-=Noam=-
p.s I cannot change name of tables since its a customer DB I need to connect.
Im adding the C# code I use:
private static string createInsertQueryVehicle(string i_VehicleNumber, string i_VehicleMFG, string i_Truck1SerialNo, string i_Truck2SerialNo, string i_Truck3SerialNo)
{
string tryout = string.Format("INSERT INTO {0} ([{6}], [{7}], [{8}], [{9}], [{10}]) VALUES(RIGHT('{1}',10),'{2}','{3}','{4}','{5}')",
TableName, Vnum, Vinfo, T1Serial, T2Serial, T3Serial, VnumFieldName, VinfoFieldName, T1SerialFieldName
T2SerialFieldName,T3SerialFieldName);
return tryout;
}
at end tryout holds:
INSERT INTO Vehicles ([Vehicle Number], [Vehicle Mfg], [Truck #1 Serial Number], [Truck #2 Serial Number], [Truck #3 Serial Number]) VALUES(RIGHT('000000010001525',10),'קרונות משא','ר40011_1','ר40011_2','')
EDIT:
Just wanted to add my solution at end:
At the end the best solution I could get was to use accesses as the connection point using linked tables to the paradox tables, at end handling it as an accesses DB.....
Hope it helps someone.

You need to use the quoted identifiers while having special character in field or table names. The double-quote (") should be what you're looking for.
Besides, I do believe that the Borland Database Engine is required in order to work against a Borland database such as Paradox. At least, that what I have always been told to, though I have never yet experienced such architecture, since I was using Delphi when working with Paradox.

As you founda (somewhat convoluted) solution...
Might be worth putting an ODBC trace on and seeing how Access is passing the field name that's causing the issue. It may just be an escape sequence that paradox accepts for the hash (#) or something similar. Just a thought.

I was able to reproduce the problem by creating a table (Table1) with a column that has number sign (col#). Like:
INSERT INTO `Table1.db` (`col#`) VALUES ('a')
Where I run this SQL I get this Error:
The INSERT INTO statement contains the following unknown field name: 'col#'. Make sure you have typed the name correctly, and try the operation again.
This seems to be a bug Microsoft JET provider. The only workaround is found is to insert the value into another column like
INSERT INTO `Table1.db` (`col1`) VALUES ('a')
And then update the col# column:
UPDATE `Table1.db` SET `col#` = col1
I found other problems with the JET provider. For example, you will get this wrong error if the table is does not have a primary key or password protected:
Operation must use an updateable query.

Related

How do I insert a new record into an Access Database with an autonumber field using OleDb in C#

I am trying to implement a database in one of my project. The table thats giving me a problem is structured as follows.
Table Savegame:
SaveID(autonumber),
Username(Long text),
GameTitle(long text),
Savestate(short number)
I am trying to insert into the table using the following code
cmd.CommantText - "INSERT INTO Savegame(Username,GameTitle,Savestate) Values('"+username+"','"+game+"','1')";
Everytime I run the code I'm told that I cannot leave the SaveID field empty since its NOT NULL.
Any help would be much appreciated.
At least, supply a number for SaveState:
cmd.CommantText - "INSERT INTO Savegame(Username,GameTitle,Savestate) Values('"+username+"','"+game+"',1)";
Also, are you sure, that the other fields are Long Text, not Short Text?

Changing ntext to nvarchar using C# and Entity Framework

I have to add sorting to existing database created in SQL Server. The problem is that this database contains ntext columns that are not supported by LinQ's OrderBy method. The database was written in a code-first approach, so I have access to template of database, but I can't look at ready database working on the server.
I've tried to change string type properties marking them as
[Column(TypeName = "nvarchar(MAX)")]
but then I got a
Sequence contains no matching element
exception which I don't know how to fix.
This is the way that I wanted to sort my data(i got exception right in the below instruction:
MyDatabase.MyTable.OrderBy(x => x.MyRow).Load();
Before I changed TypeName to nvarchar, I've got this error:
Large objects (ntext and image) cannot be used in ORDER BY clauses
Can somebody help me with fixing things up to make possible to sort data from database?
I'll appreciate any kind of help. Thanks in advance!
In T-SQL you can solve this in many ways, may be you can adopt one of them for you too?
ORDER BY (cast MyTextCol as nvarchar(max))
create a view from
this table with that field casted as nvarchar(max) and use it
instead of your table(even in future)
ALTER TABLE myTable ALTER
COLUMN myTextCol nvarchar(max)
The last one solves your problem and takes no time to be made: it's just a metadata operation, nothing will reorganizen in your table for existing rows

Cannot insert data using tableadapter.insert method due to an Auto-Increment field

I need your help since I cannot locate an answer anywhere on the web for my problem.
I'm using C# and I have a table called "People" and I want to use an TableAdapter to add/delete to/form that table. I'm using an sdf file as my database as a "Microsoft SQL Server Compact 4.0 (.NET Framework Data Provider for Microsoft SQL Server Compact 4.0)" Data Source.
my code looks like this:
*peopleTableAdapter.Insert(0, byte.Parse(cbAddType.SelectedIndex.ToString()), txtAddName.Text, txtAddCompany.Text, txtAddPhone.Text,
txtAddMobile.Text, txtAddEmail.Text, txtAddAddress.Text, txtAddNotes.Text);
peopleTableAdapter.Update(this.hisabati_DBDataSet.People);*
the table contains a field called "ID" which is an auto-increment field with the following
attributes:
Allow Nulls: No
Unique: Yes
PK: No
the first param in the Insert method is asking for the ID, and if I don't enter a value, I'll get a compile error that a value is needed. If I enter a value (as I'm entering 0 above) I get the following error:
Err Msg: Cannot modify that column
Err HRESULT: -2147467259
I know how to insert using Command.ExecuteNonQuery method, but I'm trying to use the TableAdapters throughout my application as it looks like a more elegant way to write and maintain the codde...Any Advice?
Thanks much
You need to change the InsertCommand and UpdateCommand of the table adapter. Remove the Auto-Increment column name and values from the set part of those commands.
Instead of using that method specifically, create a new row via your People Dataset, then use the TableAdapter to update from that.

Using SQLite ADO.Net Provider Need to Put GUID Directly Into Query's Where Clause Without Use of a Parameter

Is there anyway to just have the GUID be part of the SQL Query itself without using a parameter?
Let me explain exactly what I am trying to do and why. I am working with an existing application that uses an ADO.Net to create and connect to a SQLite database. The current structure of the database and the method for querying it are horrendous. I am in the midst of a redesign of how it works fundamentally. However, that is not something that can be accomplished quickly. While that redesign is being completed, I have a situation that needs a band-aid solution. As a heads up, the reasoning behind the initial implementation of the code is obscure and appears to have been built by someone who had little database knowledge. Refactoring the entire database to not need this situation is the ultimate solution, but for now I'm just looking to work within the existing structure.
The design of the database relies on GUID's to uniquely identify rows. To perform filtered retrieval of the data the system dynamically builds a command that has an IN clause listing the GUIDs that should be retrieved. Right now the GUIDs are inserted into the query by using a parameter with type GUID, so the query will look like
SELECT * FROM data_table WHERE guid_col IN( ?, ?, ?, ?)
The problem comes in when I need to retrieve a relatively large amount of information. SQLite has a limitation of a 1000 parameters in a single query. If I need to pass in more than a 1000 GUIDs for the retrieval the query will just break. When building the above string it loops over a list of GUID's to insert the question marks and create the paramters. My band-aid fix to the problem was going to be to have the GUID value directly inserted into where the question marks are currently and forego having parameters in the query. After all, its kind of using parameters for a purpose they don't need to be used for.
The problem with this 'solution' is that I can't seem to get the GUID to match the data in the column i.e. the query is always returning null. I understand that GUIDs are not a native type to SQLite and underneath it is actually being represented as a BLOB (yes I am sure we are using the BLOB and not the string representation). Yet, I've been unable to get the query to execute correctly.
I've tried all the following so far:
I've tried calling ToString() on the GUID so the query looks like
SELECT * FROM data_table WHERE guid_col IN
( 'b5080d4e-37c3-4286-9c3a-413e8c367f36', 'aa0ff789-3ce9-4552-9840-5ed4d73c1e2c')
I've tried calling ToString("N") on the GUID so the query looks like
SELECT * FROM data_table WHERE guid_col IN
( 'b5080d4e37c342869c3a413e8c367f36', 'aa0ff7893ce9455298405ed4d73c1e2c')
I've tried calling ToString("B") on the GUID so the query looks like
SELECT * FROM data_table WHERE guid_col IN
( '{b5080d4e-37c3-4286-9c3a-413e8c367f36}',
'{aa0ff789-3ce9-4552-9840-5ed4d73c1e2c}')
I've tried calling ToByteArray() on the GUID and putting the result into the query by adding each byte to the string calling ToString("X") on each byte so the query looks like
SELECT * FROM data_table WHERE guid_col IN
( '4ED8B5C33786429C3A413E8C367F36', '89F7FAAE93C524598405ED4D73C1E2C')
In reading the SQLite documentation I read the following "BLOB literals are string literals containing hexadecimal data and preceded by a single "x" or "X" character. If I try to apply this to my query so it looks like
SELECT * FROM data_table WHERE guid_col IN
( x'4ED8B5C33786429C3A413E8C367F36', x'89F7FAAE93C524598405ED4D73C1E2C')
I get an error saying that "x" is not a recognized symbol.
Is it possible to get the GUID into the query string without the use of the parameter?
I suggest that you use a temporary table for something like this. For example...
PRAGMA temp_store = MEMORY;
CREATE TEMP TABLE tbl_guids (guid_col text);
INSERT INTO tbl_guids VALUES ('b5080d4e-37c3-4286-9c3a-413e8c367f36');
INSERT INTO tbl_guids VALUES ('aa0ff789-3ce9-4552-9840-5ed4d73c1e2c');
... more inserts ...
SELECT * FROM data_table WHERE guid_col IN ( SELECT guid_col FROM tbl_guids);
DROP TABLE tbl_guids;
Make sure to wrap a transaction around all of the INSERT INTO statements. This will help with performance by a ton. Also SQLite allows for temp tables to exist entirely in memory by setting PRAGMA temp_store = MEMORY
If you have a multiple users accessing the table at the same time sharing the same connection, you will need to create some uniqueness with the temp table such as adding a random number to the table name such as tbl_guids_9087.
You can pass GUID's in as strings if you set "BinaryGuid=False" in the connection string.
If this is done, "ToString()" should work fine.

Using MSSQL CE in C# getting error, and can't figure our why,

I have a problem with inserting into a MSSQL CE database,
locCon.Open();
SqlCeCommand locCmd = locCon.CreateCommand();
locCmd.CommandText = "INSERT INTO user (ID,FName,LName,Email) VALUES('"+this.id+"','"+this.fName+"', '"+this.lName+"','"+this.email+"')";
locCmd.ExecuteNonQuery();
When running this I get
There was an error parsing the query. [Token line number = 1, Token line offset = 13, Token in error = user]
Now i cant see anything wrong with the query although this is the firsr time ive used MS SQL of examples ive seen the syntax for mysql and msssql are identical well for inserts anyway. Is there soemthing obviously wrong with this?
Thanks
I think "user" is a reserved word in the database. Try replacing this:
INSERT INTO user (ID,FName,LName,Email) VALUES (
with this:
INSERT INTO [user] (ID,FName,LName,Email) VALUES (
(I think it' square brackets for MSSQL CE, since it is for other MSSQL engines.)
The square brackets basically tell the query engine, "This is an identifier for an object in the database." They're commonly used to wrap the names of database objects which contain spaces, since those otherwise wouldn't parse correctly. But it's also useful for objects which are reserved words.
You may have to put brackets around the user part like so:
INSERT INTO [user]
this is because user can be a reserved word. putting [] around reserved words in SQL allows them to be used as field and table names.
One other major point is that you are constructing your query from some text inputs. This exposes you to SQL injection attacks. To avoid this I would highly recommend that you use Sql Parameters instead which help to prevent this. See this link:
http://msdn.microsoft.com/en-us/library/ff648339.aspx

Categories

Resources