问题
I am attempting to use a query to select everything from a table using one - three parameters;
SELECT * FROM PlantAreaCodes
WHERE (@AreaCode IS NULL OR AreaCode = @AreaCode)
AND (@AreaName IS NULL OR AreaName LIKE @AreaName)
AND (@Comments IS NULL OR Comments LIKE @Comments);
Here is the c# code for my query:
mySqlCommand = mySqlConnect.CreateCommand();
mySqlCommand.CommandText = "SELECT * FROM PlantAreaCodes WHERE (@AreaCode IS NULL OR AreaCode = @AreaCode) AND (@AreaName IS NULL OR AreaName LIKE @AreaName) AND (@Comments IS NULL OR Comments LIKE @Comments);";
mySqlCommand.Parameters.Add("@AreaCode", MySqlDbType.Int32);
mySqlCommand.Parameters.Add("@AreaName", MySqlDbType.VarChar);
mySqlCommand.Parameters.Add("@Comments", MySqlDbType.Text);
mySqlCommand.Parameters["@AreaCode"].Value = (string.IsNullOrEmpty(Convert.ToString(PModel.AreaCode)) ? (object)DBNull.Value : PModel.AreaCode);
mySqlCommand.Parameters["@AreaName"].Value = (string.IsNullOrEmpty(PModel.AreaName) ? (object)DBNull.Value : PModel.AreaName);
mySqlCommand.Parameters["@Comments"].Value = (string.IsNullOrEmpty(PModel.Comments) ? (object)DBNull.Value : PModel.Comments);
mySqlReader = mySqlCommand.ExecuteReader();
This query allows for the user to search for one, two, three or no fields without throwing any errors, however it only works with nullable types. Therefpre since PModel.AreaCode is an int, the search uses 0 instead of null. ie.
SELECT * FROM PlantAreaCodes
WHERE (NULL IS NULL OR AreaCode = NULL)
AND (NULL IS NULL OR AreaName LIKE NULL)
AND (NULL IS NULL OR Comments LIKE NULL);
Which will return no fields because AreaCode = 0 is a valid query.
I have tried making AreaCode nullable by declaring int? AreaCode = null, but this doesn't work. This returns all fields, instead of just one, same as if I used the default null:
SELECT * FROM PlantAreaCodes
WHERE (110 IS NULL OR AreaCode = 110)
AND (NULL IS NULL OR AreaName LIKE NULL)
AND (NULL IS NULL OR Comments LIKE NULL);
However this query returns one field:
SELECT * FROM PlantAreaCodes
WHERE (110 IS NULL OR AreaCode = 110)
AND ('%General%' IS NULL OR AreaName LIKE '%General%')
AND (NULL IS NULL OR Comments LIKE NULL);
This returns all fields containing the word 'General' in the Name:
SELECT * FROM PlantAreaCodes
WHERE (NULL IS NULL OR AreaCode = NULL)
AND ('%General%' IS NULL OR AreaName LIKE '%General%')
AND (NULL IS NULL OR Comments LIKE NULL);
How can I use non-nullable types in this query?
回答1:
Ok so I got this working. The main issue was that this needs to compare null with null, however an int can't be null as it is a value type.
So I had to do some tweaking with my code and I got this working with the workaround
int? AreaCode = null;
This allowed me to change up my code:
mySqlCommand.Parameters["@AreaCode"].Value = (PModel.AreaCode.HasValue ? PModel.AreaCode.Value : object)DBNull.Value );
For all those who aren't aware of what's happening here:
The operator ? gives a Value Type the ability to have no value, so it can = null.
ie.
int n = 0;
int? n = null;
bool b = false;
bool? b = null;
来源:https://stackoverflow.com/questions/23729067/command-parametersname-value-correct-syntax