My C# SQL Select statement is not picking up any records in my table - sql

I have 4 records in my SQL table that and I'm doing a SQL select statement to select records based on a certain criteria but I'm not picking any records up. Can someone please help?
Here is my SELECT statement:
string Sql = "";
Sql = #"SELECT * FROM " + _dtlName + "
WHERE Shipper_No = '" + sidNo + "'
AND Job_Code != '" + "R" + "'";
I have 3 records that have a Null for Job_Code and 1 record that has an R.
Based on that, I should pickup the 3 records with the NULL Job_Code but it returns 0 records.

I suspect the problem is that a comparison between any non-null value and a null value doesn't return a value of true or false, but null. So your query should probably be:
string sql = "SELECT * FROM " + _dtlName + " WHERE Shipper_No = #ShipperNo " +
"AND (Job_Code IS NULL OR Job_Code != 'R')";
(Note that I've extracted a parameter for Shipper_No - you shouldn't be including values directly in your SQL like that. Obviously you'll need to then set the parameter value in the SQL command.)
Also note that <> is more common in SQL to represent "not equal to", but I believe T-SQL allows either form.

Try,
Sql = #"SELECT * FROM " + _dtlName + " WHERE Shipper_No = '" + sidNo + "' AND Job_Code NOT IN ('R')";

I think your query should be more like this since you want to select the NULL values.
string Sql = String.Format("SELECT * " +
"FROM {0} " +
"WHERE Shipper_No = {1} AND " +
" Job_Code IS NULL",
_dtlName, sidNo)

Related

Multiple conditions in SELECT Statement

I am checking my database to see if there are any overlapping appointments. It works for ADDing appointments, but when I go to UPDATE my SQL counts the record I am updating as an overlapping appointment when I try to change it. Here is the SQL I am using in the UPDATE statement.
"SELECT * FROM appointments " +
"WHERE ('" + start + "' BETWEEN Start and End OR '" + end + "'
BETWEEN Start AND End OR '" + start + "' > Start AND '" + end + "' < End AND
Appointment_ID <> " + id + ")";
This still pulls the record with the appointment id that I'm giving it. Anyone have any suggestions on how to exclude any appointments that have the id I'm updating but still meeting the other criteria.
currently, you are only checking for the id of the appointment to update when the third clause you have chained with ORs triggers because of the order of operations for OR and AND. Your query fetches a result when the start date is overlapping with the appointment OR your end date is is overlapping with the appointment OR it has a different ID and the dates are encapsulating the appointment.
Also, you shouldn't need to have brackets around your whole WHERE clause but you can use the opening bracket and move the closing bracket to make sure that the condition with the id is always evaluated like so:
"SELECT * FROM appointments " +
"WHERE ('" + start + "' BETWEEN Start and End OR '" + end + "'
BETWEEN Start AND End OR '" + start + "' > Start AND '" + end + "' < End) AND
Appointment_ID <> " + id;

HSQLDB - updatable statements don't work with "SELECT TOP" or "ORDER BY"

I'm using HSQLDB and preparedStatements just fine, but if I include either "SELECT TOP" or "ORDER BY" in my SQL statement, when I call updateBoolean (or UpdateInt, etc), I hit an exception:
java.sql.SQLException: attempt to assign to non-updatable column
This sample code works fine:
preparedStatement = connection.prepareUpdatable(
"SELECT " + MyTable.COL_ID + ", " +
MyTable.COL_READ +
" FROM " + MyTable.NAME +
" WHERE " + MyTable.COL_LOCAL +
" =? AND " + MyTable.COL_REMOTE +
" =?",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
preparedStatement.setString(1, localAddress);
preparedStatement.setString(2, remoteAddress);
ResultSet rs = connection.query(preparedStatement);
if (rs.next())
{
rs.updateBoolean(MyTable.COL_READ, isRead);
rs.updateRow();
}
I get the exception if I change "SELECT" to "SELECT TOP". Or if I append this to the SQL statement:
" ORDER BY " + MyTable.COL_RECEIVED_TIMESTAMP + " DESC"
Thanks for any help.
NickB
An updatable SELECT statement cannot have TOP n, LIMIT or ORDER BY. This restriction is imposed by the SQL standard. Your SELECT becomes not-updatable when you add one of those keywords.
It is possible to use a subquery in a WITH clause with the above keywords and the SELECT is updatable.
CREATE TABLE t (a int, b int, PRIMARY KEY(a));
WITH SUBQ(COL) AS (SELECT TOP 1 a FROM t)
SELECT * FROM t WHERE a IN (SELECT * FROM SUBQ)

Insert Into Select SQL Server

I am trying to do a kind of insert into select statement. I want to insert one column as standard and the second through a select. However this is not working:
queryString = "INSERT INTO Words (Word, SortedId) VALUES ('" + words[i] + "', (SELECT TOP 1 SortedId FROM SortedWords WHERE SortedWord = '" + sortWord(words[i]) + "'))";
SortedWords is already filled with data. But at the moment i get this error
{"There was an error parsing the query. [ Token line number = 1,Token line offset = 50,Token in error = SELECT ]"}
Note:
not sure if i need the TOP 1 bit or not, get error either way. But I obvs only want to insert one row.
Change your query to
queryString = "INSERT INTO Words (Word, SortedId) SELECT '" + words[i] + "', (SELECT TOP 1 SortedId FROM SortedWords WHERE SortedWord = '" + sortWord(words[i]) + "')";
Also, instead of concatenating strings to get your query, use parameters to avoid SQL injection.
Try next and better practice to use a SqlParameters:
INSERT INTO words
(word,
sortedid)
(SELECT TOP 1 #Word,
sortedid
FROM sortedwords
WHERE sortedword = #SortedWord)
And before execiting query create a parameters(C#)
//Assume you have a SqlCommand object(lets name it command)
command.Parameters.AddWithValue("#Word", words[i]);
command.Parameters.AddWithValue("#SortedWord", sortWord(words[i]));

How to combine asterix syntax with table abbreviations

Is it possible to combine * syntax with table abbreviations?
I want to do something like:
"SELECT subfunds.* FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
The above code gets a syntax error
"invalid reference to FROM-clause entry for table "subfunds".
I already found that if I do
"SELECT * FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
then I get all fields from both tables rather than from the subfunds table only.
So how do I get all fields from the first table (and none of the other tables' fields) in my answer set while also being able to use the single-letter table abbreviations?
Change your code to this and you will get all fields from subfunds.
"SELECT S.* FROM subfunds S" +
" INNER JOIN funds F ON S.id_fund = F.id" +
" WHERE F.fund_short IN('" + stSQLFundList + "')"
If you are using an alias, then you want to reference that table by it's alias.

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)