Reputation: 5083
Let's say in my Excel sheet, I have the following "table":
ZipCodes |
---------+
4059 |
5806 |
4529 |
I need to get the data from a SQL Server view WHERE column ZipCodes
has one of the values in my Excel table.
I want the user to be able to add as many ZipCodes
as he wants, while not adjusting the query manually.
I've looked that this question but I cannot get it working.
I'm stuck with passing a list of values to the sql query. It's working if I am passing a single ZipCode.
Sth. like this would help me:
WHERE ZipCode IN (SELECT * FROM [sheet2$a1:a2])
but that's breaking the query.
Upvotes: 1
Views: 1051
Reputation: 95544
One solution here would be to use OPENROWSET
. After discussion, it does appear that the location of the Excel file can and will change; this is fine but means we need to build a dynamic SQL solution, as OPENROWSET
requires literal strings for it's parameters (no variables).
Firstly, I don't know what what version of the ACE Drivers you have installed. As a result in my code I am using the drivers I have installed; which are the 2010 drivers (version 12). If that's not the version you're using, you'll need to change the value that I comment.
Normally, an OPENROWSET
query might look like this:
SELECT *
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', --This declares the Driver. You may need to change this
'Excel 8.0;HDR=YES;;Database=\\YourFileServer\yourShare\YourFile.xlsx',
'SELECT *
FROM [Sheet1$A1:G];');
This'll return all rows from columns A
through to G
, starting at Row 2. Row 1 will be assumed to contain the Header (HDR=YES
); if you don't have headers use HDR=NO
.
The problem here is that we can't pass a a variable here. Thus we need to do something more dynamic. This gets you something along the lines of:
DECLARE @File nvarchar(500); --This would be your parameter
SET @File = N'\\YourFileServer\yourShare\YourFile.xlsx';
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT *' + NCHAR(10) +
N'FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',' + NCHAR(10) +
N' ' + QUOTENAME(N'Excel 8.0;HDR=YES;Database=' + @File,N'''') + N',' + NCHAR(10) +
N' ''SELECT *' + NCHAR(10) +
N' FROM [Sheet1$A1:G];'');';
PRINT @SQL;
EXEC sp_executesql @SQL;
Now, finally, you want to use this data against your table/view. This, therefore, might finally look something like this (assuming your view is called Customer_vw
, the data in the excel file in in column A, and the column in both datasets is called ZipCode
):
DECLARE @File nvarchar(500); --This would be your parameter
SET @File = N'\\YourFileServer\yourShare\YourFile.xlsx';
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'WITH ExcelZips AS (' + NCHAR(10) +
N' SELECT ZipCode' + NCHAR(10) +
N' FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',' + NCHAR(10) +
N' ' + QUOTENAME(N'Excel 8.0;HDR=YES;Database=' + @File,N'''') + N',' + NCHAR(10) +
N' ''SELECT *' + NCHAR(10) +
N' FROM [Sheet1$A1:A];''))' + NCHAR(10) +
N'SELECT [YourColumns]' + NCHAR(10) +
N'FROM Customer_vw C' + NCHAR(10) +
N' JOIN ExcelZips EZ ON C.ZipCode = EZ.ZipCode --Note that EZ.ZipCode will not show in intellisense' + NCHAR(10) +
N'WHERE ...;'; --You'll need to complete the WHERE here, and add any ORDER BY etc.
PRINT @SQL;
EXEC sp_executesql @SQL;
Note that I have PRINT
statements in the queries. These are your friends. I (personally) suggest that you comment out the EXEC
statements first, and just use the PRINT
statements. Check that the output from the PRINT
looks correct. If it does then run it, and if you get an error trouble shoot the output from the PRINT
, rather than the dynamic SQL. Once you've fixed the non-dynamic SQL, propagate the changes to the dynamic SQL.
Hopefully that explains everything. If you have any questions, please do ask.
Upvotes: 2