1
I'm using a number of Excel files to connect to an SQL Server database, fetching sales data for a particular product number which is specified in a cell in the Excel sheet.
This was set up by defining parameters in the SQL connection with
SELECT ProductCode, Sales
WHERE ProductCode = ?
and specifying a cell in the worksheet that contains the product number. This works fine, however I now want to extract the sales for a number of products at once. I've created a comma-separated list automatically in Excel, but trying to use this as the parameter always results in this error message:
Syntax error message screenshot
I'm entering the SQL code as WHERE ProductCode IN ?
as ideally I'd like to have the parameter cell able to change dynamically within Excel, but I've also tried WHERE ProductCode IN (1,2,3)
or WHERE ProductCode IN (N'1', N'2', N'3')
and various other different syntax. I've also replicated this syntax in the Excel-generated list of product numbers. (1,2 and 3 in this case being example product codes).
Some alternatives I could use would be having WHERE ProductCode=? OR ProductCode=? OR ProductCode=?
etc and specify each as a separate parameter, but it's likely to be at least 200 product codes so this is far from ideal, it also means I'll have to manually edit the SQL code whenever a greater number of codes need to be fetched than however many cells I've set as parameters, and most colleagues don't have the SQL knowledge to do this in my absence either.
Probably I'm just using the incorrect syntax, but hopefully someone will be able to point out where I might be going wrong. The error message is the same no matter what format I select so I can't figure out what the problem might be.
This is the full query which does work:
SELECT
PRODUCT.ProductCode
,SALES.Quantity
,SALES.Date
FROM
SALES
INNER JOIN PRODUCT
ON SALES.ProductCode = PRODUCT.ProductCode
WHERE
((SALES.Date >=? AND SALES.Date<=?)
AND PRODUCT.ProductCode=?
Just added, it's not much more complex than what was already in the question tbh, but hope it helps. – David H – 2019-09-04T13:22:43.583
Does the query with the only table
SELECT ProductCode FROM product WHERE ProductCode IN (?,?,?,...)
works with IDs list? Does you transfer the list into your query as a lot of separate parameters, not as one CSV parameter? – Akina – 2019-09-04T13:26:03.273It actually seems to work now if I type in a few item numbers directly into the query 'WHERE SALES.ProductCode IN (1,2,3)'. But using the parameter with the exact same values in the target cell still gives the error message. – David H – 2019-09-04T14:17:05.930
It must be parameterS, not single parameter. – Akina – 2019-09-04T14:37:42.977
But if I change the statement to WHERE ProductCode IN (?,?,?) that will require 3 separate parameters, in 3 different cells, correct? I did try something similar already but that requires me to set new parameters if the number of product codes requires increases, which I'd ideally like to avoid as I have to make the file "foolproof" for other users who have no knowledge of how to alter the SQL code. The final file will need to have several hundred product codes, so I would then need to maintain those several hundred parameters in the dialog window. – David H – 2019-09-04T14:42:08.557
if I change the statement to WHERE ProductCode IN (?,?,?) that will require 3 separate parameters, in 3 different cells, correct? Of course. If you want to send ONE parameter which contains ALL values then you must use any function which will "unpivot" this parameter into one more source table (and use proper parameter format). For example, it can be OPENXML()... or VALUES()... – Akina – 2019-09-04T18:33:06.310
How would that work exactly? In order to put all the codes into one comma-separated list, I've had to concatenate them, which presumably is what is stopping them being recognised as values. I've tried a few permutations of VALUE() (there doesn't seem to be a VALUES() function), is there another way of combining all the values into a single parameter? – David H – 2019-09-05T07:05:54.077
Sorry, VALUES() cannot achieve the goal... If your SQL server is 2017+ (compatibility level >=130) you may use STRING_SPLIT() function for to parse single parameter with CSV values into a rowset (using it in FROM clause as a source table). If your server is more ancient you may use OPENXML() or, for example, one of solutions from https://stackoverflow.com/questions/697519/split-function-equivalent-in-t-sql
– Akina – 2019-09-05T07:21:28.787Am I right in thinking that would require me to create new tables within the database? I don't have write access to the database unfortunately, I can only read data from the existing tables. – David H – 2019-09-05T07:57:26.087
Am I right in thinking that would require me to create new tables within the database? No. I'll show draft sample code for SQLserver 2017+ as an answer to explain. – Akina – 2019-09-05T08:16:39.497