Of course... But it isn't actually just that. You have to add the OR @colName IS NULL,
Um.. no you dont, you jsut simply dont concatenate the parameter on
I think you may be missing the point i'm making. Youre saying:
"I have 26 options, my user selects 2 of them (suppose item 7 and 13) and concatenate those 2 on as values:
SELECT * FROM table WHERE 1=1
CONCAT: AND col7 = 'hello'
CONCAT: AND col13 = 'world'
Your SQL ends up as SELECT * FROM table WHERE col7 = 'hello' AND col13 = 'world'
I'm saying
"I have 26 options, my user selects 2 of them (suppose item 7 and 13) and concatenate those 2 on as parameters then set the values:
SELECT * FROM table WHERE 1=1
CONCAT: AND col7 = @col7
PARAMETERS.ADD('@col7', 'hello')
CONCAT: AND col13 = @col13
PARAMETERS.ADD('@col13', 'world')
My SQL ends up as: SELECT * FROM table WHERE col7 = @col7 AND col13 = @col13
AND THE PARAMETERS COLLECTION has 2 entries, one for the @col7 and one for the @col13
This is more work on the client side, but it can be done. I'm also pointing out that it can be done in SQL (via the col = @param OR @param IS NULL method), it depends how much work you want to put into doing it on the client side.. Imagine if you made a tableadapter partial clas sthat had a sub that took an array of values and an array of column names, and then iterated the arrays and built a parameterised string with them and ran it.. yep, you can do that.. but theres a faff somewhere along the line with making the array.. All i'm saying is that with the (col = x OR x IS NULL) method, you write the SQL once, properly (because cmon, we are pro developers if we are doing this, not some newbie; we can get this right, and we can tell what the SQL is doing simply by looking at the parameters collection..) and not have to fuss over it..
Upshot, I dont care how you write the SQL, whether concatted or "col = x OR x IS NULL" style, SO LONG AS YOU USE PARAMETERS
You can use parameters in 99% of situations, and the situations you cant use tham, you should question whether you should be doing the data access that way..
Parameters:
Stop weird characters screwing up your SQL string
Stop SQL injection
Allow the DB to better plan the query
Allow reuse without recompilation
All upsides, no downsides. There is nothing about concatting a bunch of values together to form an SQL that has ANY merit, in 99% of situations (and as noted, the 1% are cases like when you want to parameterise what the table name is.. You cant do SELECT * FROM @table_name, and good job too.. because parameterising something like that means your data structure you interact with is not consistent or fixed, and that makes it hard to code. Its a step beyond what is required in 99% of situations. Trust me.
That gives a pretty complex SQL expression. Even in the event that you just search in ColA from the A to Z columns, you have 26 * 2 conditions and you have to put parenthesis and OR to make a non existent field work correctly.
I think we have different definitions of complex. I'll email you the last SQL i wrote (it's 32 kilobytes long) and you can check out something I regard as complex
The database doesnt particularly care about 52 checks; most of them are instantly discountable as true in your cases anyway (cause the user doesnt pick all 26). Remember that there are 52 predicates but only 26 parameters.. that promotes another plus point of parameters. if you have a 4 meg parameter to upload, into 3 different columns, you can either upload it 3 times (your way) by having a 12 meg long SQL or once, using a parameter (4 meg)..
And you still cannot see the values in the SQL query to debug it.
Okay, this might be as a result of using a basic programming language like VB.NET because it doesnt show you lists, or private members of objects. Upgrade to C# and your deugger experience will improve considerably. Point to a collection in C# and you see the members, not a "to access an indexed property you must provide..." tooltip. The values are there for your inspection, you have only to look!
SELECT Name FROM MyTable WHERE (Name = @Name OR @Name IS NULL) AND (Color = @Color OR @Color IS NULL) AND (SomethingElse = @SomethingElse OR @SomethingElse IS NULL) ... ORDER BY Name
I dont know about anyone else, but i'm quite particular about indenting and pretty printing my SQLs because i find nothing more unreadable than the gash mess that most people (and even the .net wizard) makes of an sql all on one line
Then you will look at the parameters from the SqlCommand and look for one that is not null.
Yes, but I wrote the query, so I should know what I'm doing! I've looked at other developer's codes, and run their queries in VS2005's analyzers and they come out just fine, and I can pause and look and check. I also write queries in test, with fixed values, and then parameterize them later when I know they work. Maybe its how we differ in an approach to the problem
SELECT Name FROM MyTable WHERE (Color = 1)
I take your point, but it's really only one that an inexperienced or SQL hating programmer would make. If there's a problem with an SQL as critically simple as SELECT * FROM person WHERE name = 'smith' then your company needs to hire a database nerd
I take your point of running queries direct, yes it saves you some time.. but then, how hard can it be to knock up a class that simply replaces all the @parameters in your sql text with the value (using the parameters collection) so you can TEMPORARILY run it in an analyzer
It is true that parametrized query produce clean code to use and create, but you reach a similar point of simplicity by encapsulating the query creation in an object.
Indeed. It's called the VS2005 table adapter wizard.. and isnt it strange, that Microsoft chose the parameterised route too? Are you telling them they do it the wrong way round too?
Add a few static methods to convert the DateTime object or raw String to a String ready for adding to the query and you got something that is nearly as clean as the parametrized query. Without the complexity in debugging and the limitations.
No, you've got something that is a mess or coercion, and in full form might be megabytes long because of all the values stuffed in there. You seem to be trying your hardest to convince me that when you write a VB program, you Dim everything as a String, and when you need to do some date math, for example, you parse your strings to DateTimes, do the math, and store the result in another string..
Show me some of your VB code. If it contains so much as one Dim x as Integer, Dim y as DateTime, Dim z as (any Type other than String) then youre effectively being a hypocrite, because you use non-string variables throughout your VB, but then advocate that every variable in SQL should be of type string, and conversion should take place when appropriate
SELECT name FROM MyTable WHERE CategoryId IN {@CategoryId1, @CategoryId2, ... @CategoryIdN}
is not really an option if the number of categories is variable (the categories are in a table). It may be possible to write a parametrized query like this :
SELECT name FROM MyTable WHERE CategoryId IN @CategoryIdList
In is something that most pro SQL developers avoid tenuously.. I agree it makes some things very convenient and easy, and it's a syntactic convenience for writing out hundreds of ORs (not that you should use IN on lists longer than you'd write by hand) yourself that most databases cannot parameterize, so we have other tricks to work around those situations.. and I'll readily concede that those situations come up far more often than the 1% (or less) that parameterization for a Quirky Reason is impossible..
and give it an array or collection in parameter, I must admit I never tried but I doubt it and the SqlCommand class is sealed so there is no way to add this with inheritance. The number of sealed classes and not virtual methods and properties is one of the thing I miss from Java btw...
Mmm.. it doesnt work, typically. In Oracle we tend to provide a list of values delimited by something that doesnt occur naturally in any of the values and bust it out using a WITH clause, effectively forming a temporary in-memory table that we can join to. It performs a lot better than IN too, in most of the cases where I use it.
It does tend to make things a bit more tricky, which is why i devolve to stored functions that return cursors when I have to do something like that.. Fortunately, it's exceptionally rare that a user demands something I cannot otherwise assemble simply on the client side