DELETE FROM table WHERE var = value does not remove entries - sql

So I fetched some data from a mdb file in c# via
"SELECT * FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE Note = '" + listBox2.GetItemText(listBox2.SelectedItem).Replace("'","\'") + "'";
which selects the right data, here it is
SELECT * FROM Main WHERE Note ='Hello'
The mdb data structure looks like this being plotted as a CSV-file:
"Record ID";Status;Placement;Private;Category;Note;Blob
14341665;4;2147483647;True;3;"""Hello"" - Neues
But when I try to remove entries with
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" LIKE '" + dr[0] + "';";
or
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" = '" + dr[0] + "';";
which looks like for instance
DELETE FROM Main WHERE "Record ID" LIKE '14341665';
The entries just stay there. I can rerun the select command even restart my application, the mdb is not changed.

Is record ID a numeric field? If so, lose the quotes.
DELETE FROM Main WHERE [Record ID] = 14341665;
Note that spaces in field (column) names will always be a problem. Such columns names have to be enclosed in square brackets, as do columns named with reserved words.

The record id is numeric, so don't put apostrophes around it:
"DELETE FROM " + listBox1.GetItemText(listBox1.SelectedItem) + " WHERE \"Record ID\" = " + dr[0]
Note: You should avoid using select * in production code, you should specify the data that you want returned. Also, you should use parameterised queries instead of concatenating values into the query.

if i remember correctly, "like" only works on string data, please check the data type of Record ID.
If Record ID is numeric, you may want to use database's conversion function to convert it into string before filtering using "like".
btw, remember to make sure that dr[0] is properly escaped.

Related

Automatically assigning a primary key to an entry in MS-Access via Netbeans

I am trying to insert values into a table using SQL. A user enters the values except for the primary key which is an autonumber (ID).
if (lstCarD.getSelectedIndex() == -1) {
obj.updateTable("insert into tblSCars values('" + txtBrand.getText() + "','" + txtModel.getText() + "'," + Integer.parseInt(txtSpeed.getText()) + "," + Integer.parseInt(txtWeight.getText()) + "," + Double.parseDouble(txtAcc.getText()) + "," + Integer.parseInt(txtPower.getText()) + ") ");
} else {
obj.updateTable("UPDATE tblSCars SET tblSCars.Brand ='"+ txtBrand.getText()+"','"+ txtModel.getText() + "'," + Integer.parseInt(txtSpeed.getText()) + "," + Integer.parseInt(txtWeight.getText()) + "," + Double.parseDouble(txtAcc.getText()) + "," + Integer.parseInt(txtPower.getText()) +"WHERE RunnerId="+txtBrand.getText());
}
pnlStart.setSelectedIndex(2);
lstSuperCars.clear();
getCars();
Gives me the following error:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.3.1 row column count mismatch
Which can be solved be either allowing the user to enter a field 'ID' or removing the field from the MS-Access Table (works if I do this).
I am trying to figure out how to make Netbeans automatically assign the primary key field 'ID' without having a user to enter it or removing it.
tblSCars - table that I am entering into.
There are no occurrences of field 'ID' anywhere else in the class.
Thanks in advance.
The error is kind of self-explanatory, you're not specifying what fields to insert into, and the amount of fields you specify in the insert/update query isn't equal to the total amount of fields in the table.
You can specify fields in the following way:
insert into tblSCars(Field1, Field2 ... FieldN) VALUES(Value1, Value2 ... ValueN)
UPDATE tblSCars SET Field1 = Value1, Field2 = Value2, etc.

Access: Runtime error 3075 (missing operator) in SQL update query

First time using Access and wanted to make an update query that uses a variable for its table name. Now, I've gotten myself into a web of nothing good. When I get to the part the SQL code is needed for, I get Runtime error 3075 - Missing operator in '(((" + enteredid + ".todayDate)=Format(Now()','""Short Date"")))' I've never coded in SQL, so I have no clue what operators are needed.
My code:
strSQL = "UPDATE " + enteredid + " SET " + enteredid + ".signIn = Format(Now(),""Short Time"") WHERE (((" + enteredid + ".todayDate)=Format(Now()','""Short Date"")));"
My suggestions:
You can avoid the whole Format() issue in the WHERE clause by using the Date() function instead of trying to extract just the date part of Now().
Since you are doing an UPDATE on a single table you can just use the field (column) names without the TableName. prefix.
To make your code more robust, enclose the table name in square brackets so it won't crash if the table name contains spaces or other "funny" characters.
So, the revised code would look more like this:
strSQL = _
"UPDATE [" + enteredid + "] SET " + _
"signIn = Format(Now(),""Short Time"") " + _
"WHERE todayDate = Date()"

Search AutoNumber field in Access via SQL (VB)

I'm trying to allow the 'user' to search for 'members' by searching for their member ID. Here is a screenshot of the database (design view).
https://drive.google.com/file/d/0B7pMpT1WtgKDVU5MVkFYNXJjcTA/edit?usp=sharing
If in VB I search for the ID as an Integer it produces a datatype mismatch error (see below)
https://drive.google.com/file/d/0B7pMpT1WtgKDMFVtYlFiWlpES0E/edit?usp=sharing
Sorry for asking another probably pointless question, thank you though - mean's a lot!
The error lies in this line:
sqlstatement = "Select * from Members where ID = '" + MemberID + "';"
It should be:
sqlstatement = "Select * from Members where ID = " + MemberID + ";"
Since your "ID" field is Autonumber, you're checking condition with a string which is wrong.
You're doing
"WHERE ID = '" + MemberID + "';"
in your VB code. I think this might be your
problem. I guess it thinks the ID is string,
and not int.
I am not very familiar with VB but
try it without the '' i.e. like this:
"WHERE ID = " + MemberID + ";"

Too few parameters. Expected 1 - but I have one

So I've recently been working on a VBA script to transfer an entire database of student medical records from their old one-table, 68-field, flat system to a new dynamic system with 24 related tables.
There was no issue for the first few tables, but then I ran into this. The line of code throwing the error is:
Set rstFrom = CurrentDb.OpenRecordset("select " & Flat & ".Student," & Flat & ".School," & Flat & ".Social," & Flat & ".FamilyHist from " & Flat & " WHERE 1=1")`
Flat is a String which stores the name of the flat database (this is because I'm working with a dummy database so they will need a convenient and quick way to modify the code I make to work on the real thing)
rstFrom needs to contain only the columns of the 68-field table which are relevant to the table that I'm copying to at the moment (in this case, the FamilyHistory table which really just needs the studentID and FamilyHistory) - note that the original table did not assign unique studentIDs, so I must use the name, school, and social to determine that I am dealing with the same child and look up their studentID
When this line of code runs I get the following error:
Run-time error '3061':
Too few parameters. Expected 1.
Clearly I have 1 parameter, it's:
"select " & Flat & ".Student," & Flat & ".School," & Flat & ".Social," & Flat & ".FamilyHist from " & Flat & " WHERE 1=1"
(which after parsing is):
"select Demos.Student,Demos.School,Demos.Social,Demos.FamilyHist from Demos WHERE 1=1"
The where 1=1 is required when working with Access VBA or else it only returns the first record which matches, not all matching records.
Has anyone else had this same problem as resolved it? I did notice one thing. When I change the parameter to:
"select Demos.Student from Demos WHERE 1=1"
It is able to get past this line no problem, although this causes issues later on when I need to read other data that I did not retrieve. I thought it was interesting, though, that the error seems to be coming from the SQL and not the OpenRecordset function.
Check the field names in the SQL vs what you have in table.
I think, either the field name in above SQL is misspell or you don't have one or more field (of SQL statement) in the table.
The text parameters in the insert query need to have a single quote around them. I ran into the same problem with a query using Visual C++.
Here's the code I ended up using...
void FileInterface::TblWrite(CDatabase* db, rec* r)
{
string sqlQuery = "insert into THREATS(ID,CODE,ID,LAT,LON,SHOW_A,SHOW_B) Values(" +
to_string((_Longlong)r->num) + "," +
to_string((_Longlong)r->code) + "," +
"'" + r->id + "'" + "," +
to_string((long double)r->lat) + "," +
to_string((long double)r->lon) + "," +
"1" + "," +
"1" +
")";
db->ExecuteSQL(sqlQuery.c_str());
}

How do I get around this common SQL problem

Haven't come across this in ages and when I searched for the solution I couldn't find one. I think its called overloading in SQL. Basically when I have "" (an empty string) for any parameter in this SQL I don't want to set a value in the database...
NOTE: I want to do it at a SQL level not do it at a C# level because its sloppy that way.
string Sql = "IF NOT EXISTS (SELECT * FROM tbl_FileSystemReferences) "
+ "INSERT INTO tbl_FileSystemReferences (UploadDir) VALUES (null) "
+ "UPDATE tbl_FileSystemReferences SET "
+ "UploadDir=#UploadDir, "
+ "ThumbnailDir=#ThumbnailDir, "
+ "ArchiveDir=#ArchiveDir, "
+ "RealDir=#RealDir, "
+ "FlashDir=#FlashDir, "
+ "AssociatedFilesDir=#AssociatedFilesDir, "
+ "EnableArchiving=#EnableArchiving, "
+ "AppWideDir=#AppWideDir, "
+ "FFmpegDir=#FFmpegDir, "
+ "InstallationDir=#InstallationDir ";
SqlCommand Command = new SqlCommand(Sql);
Command.Parameters.AddWithValue("#UploadDir", f.UploadDir);
Command.Parameters.AddWithValue("#ThumbnailDir", f.ThumbnailDir);
Command.Parameters.AddWithValue("#ArchiveDir", f.ArchiveDir);
Command.Parameters.AddWithValue("#RealDir", f.RealDir);
Command.Parameters.AddWithValue("#FlashDir", f.FlashDir);
Command.Parameters.AddWithValue("#AssociatedFilesDir", f.AssociatedFilesDir);
Command.Parameters.AddWithValue("#EnableArchiving", f.EnableArchiving);
Command.Parameters.AddWithValue("#AppWideDir", f.AppWideDir);
Command.Parameters.AddWithValue("#FFmpegDir", f.FFmpegDir);
Command.Parameters.AddWithValue("#InstallationDir", f.InstallationDir);
ExecuteNonQuery(Command);
I know there is a way I used to do this with stored procedure I just cant remember how (I think it's called overloading)....
Cheers,
Can you create a stored procedure rather than passing the command as text?
That way you can break each of the lines like "UploadDir=#UploadDir," into its own variable and only add it to the command if it is not null or not empty string
one way would be on a stored procedure, where you would receive all those parameters, then before the query either:
you allow to pass null
you convert each parameter to null if they are empty as:
select #UploadDir = null where #UploadDir = ''
you would do that for all your parameters, then on update query:
IF NOT EXISTS (SELECT * FROM tbl_FileSystemReferences)
INSERT INTO tbl_FileSystemReferences (UploadDir) VALUES (null)
UPDATE tbl_FileSystemReferences SET
UploadDir=coalesce(#UploadDir, UploadDir),
ThumbnailDir=coalesce(#ThumbnailDir, ThumbnailDir),
ArchiveDir=coalesce(#ArchiveDir, ArchiveDir),
RealDir=coalesce(#RealDir, RealDir),
FlashDir=coalesce(#FlashDir, FlashDir),
AssociatedFilesDir=coalesce(#AssociatedFilesDir, AssociatedFilesDir),
EnableArchiving=coalesce(#EnableArchiving, EnableArchiving),
AppWideDir=coalesce(#AppWideDir, AppWideDir),
FFmpegDir=coalesce(#FFmpegDir, FFmpegDir),
InstallationDir=coalesce(#InstallationDir, InstallationDir)