Help with creating a SQL query with optional multi-value parameters
-
Looking for some guidance in building an "advanced search" query using XML and optional multi-value parameters. I'm building a web search form to allow users to look up people based on various parameters- name, location, title, etc. These parameters are all optional and some are multi-valued. Unless someone comes up with a good reason otherwise, it seems logical to me to pass these parameters to a stored proc as an XML doc (I'm using MS SQL 2005). I DO NOT want to build a SQL statement dynamically if I can avoid it. So, I'd wind up with parameters like so:<SearchParams> <Name>MKUltra</Name></SearchParams>or<SearchParams> <State>NY</State> <State>NJ</State> <State>CT</State></SearchParams>or<SearchParams> <Name>MKUltra</Name> <State>NY</State> <State>NJ</State> <State>CT</State> <Title>Stud Muffin</Title></SearchParams>My gut says the best approach is to dump them into a temp table and do some shenanigans to restructure the data into a two-column table with "Name" and "Value" as the columns so I can JOIN on it, but I'm not sure. My main concern is joining on this table when there's no relevant parameter passes (e.g. "State", in the first example). Am I missing something obvious? Is there a better way to tackle this?
-
Answer:
By what criteria are you measuring "better" here? Faster? Simpler? More flexible? Cheaper?
mkultra at Ask.Metafilter.Com Visit the source
Other answers
Ok this is my way, but it's not the only way. I pass multi-value parameters to an SQL query as a comma-delimited string. Then I use a SQL function that take the comma-delimited string and returns a table variable. This is elegant because you can just "join" straight to the result of the function in one line. There is an excellent example (including the code for the conversion function) http://www.sql-server-helper.com/functions/comma-delimited-to-table.aspx Your search would ends up looking something like this: SELECT Users.* FROM [dbo].[Users] INNER JOIN [dbo].[myStringToTableFunc] ( "NY,NJ,CT" ) State ON Users.[StateD] = State.[String] WHERE Users.[Title] = "Stud Muffin"
pivotal
Dammit just re-read your question and saw the bit about the "optional" State parameter. This might get ugly. I would also go straight towards a dynamic SQL approach, with a test for a null parameter, but this is not nice from an optimisation point of view. Another option is to set default values for optional parameters in a stored proc. So you would have something like: CREATE PROCEDURE myProc ( @Name varchar(255) = "%%", @States varchar(1000) = "AK,CA,NY...list of ALL states", @Title varchar(255) = "%%" ) Then you can use "Like" clauses to match on Name and Title, and the "%%" will match ANYTHING if no value is passed. The full states list will return every result regardless of state if you pass nothing. To reverse the logic (e.g. return nothing if no param is passed), use an empty string as the defaults.
pivotal
Better = simpler. I'm not sure how a non-XML-based solution could achieve more flexibility, but I'm open to seeing how. http://ask.metafilter.com/65656/Help-with-creating-a-SQL-query-with-optional-multivalue-parameters#986621- I don't want to use CSV because it requires extra data manipulation before sending off and it doesn't get around the optional issue- INNER JOIN [dbo].[myStringToTableFunc] ( "" ) will always return 0 rows. I do use that technique when I'm only dealing with one parameter, but it's not flexible IMO because you need to define each parameter separately in the SP.
mkultra
To clarify- my issue isn't with single-entry parameters (name, title, etc.), because there will ALWAYS be one value passed, even if it's just an empty string (yes, I'm using LIKE for that)- it's with parameters which can occur 0+ times, the way HTML checkbox form elements are passed.
mkultra
Gah yeah sorry I'll just crawl back under my rock. I totally misinterpreted your question. http://msdn2.microsoft.com/en-us/library/ms345117.aspx has a little ditty on how to extract xml values as a table (about half way down), which gets you part way thre, but you're back to a dynamic query if the table is empty.
pivotal
Related Q & A:
- How can I optimize this dynamic SQL query in oracle with PL/SQL?Best solution by docs.oracle.com
- How to convert sql query to Hibernate Criteria query?Best solution by Stack Overflow
- How to convert my SQL query to MS Access query?Best solution by Stack Overflow
- How to convert a SQL query into hibernate criteria?Best solution by Stack Overflow
- How to present large dataset from a SQL Server query?Best solution by stackoverflow.com
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.