Directly access a CSV file using T-SQL
In this post, I’d like to talk about Comma-Separated Values in Files (i.e. CSV Files).I had a client with a need to read in a CSV file and do some subsequent processing with it. This was a very small file that didn’t regularly populate any permanent table… Its data was simply used as input to do some calculations, so using a tool like SSIS to process the file was overkill. We just needed to access the file directly with T-SQL. Let’s look at an example… In the C:\Temp folder, we have a CSV File called TerritoryData.CSV with the following contents (Ignore the /*…*/ delimiters… They are there so that sites that syndicate this blog will render the output more reliably): /* One
method we can use to directly access a CSV file using T-SQL (and the
one most recommended on various online forums) is to do something like
this:select TerritoryIDThis uses the MSDASQL provider in concert with the Microsoft Access Text Driver to read the data from the CSV File. Boy that was easy! We’re done, right? Well… not really. There are some inherent gotchas and problems with this. First of all, this approach with OPENROWSET will not work unless your server is configured to accept Ad Hoc Distributed Queries. That can easily be accomplished like so: sp_configure 'Ad Hoc Distributed Queries',1Note the name of the Driver in the query. My laptop has the Microsoft Access Text Driver installed on it… presumably because I’m on Windows 7 and Office 2010 is the only version of Office that I have installed (and, ironically, I did NOT choose to install Access). But on my old WinXP machine, there is no such driver. On that machine, I would have to use a different driver name: select TerritoryIDBy the way, note the subtle difference in that the older driver separates *.txt and *.csv with a semicolon; whereas, the newer (Access) driver separates them with a comma. You have to make sure the driver is spelled EXACTLY right. So, in a nutshell, we have to know which driver is installed in order to make this work. To see the drivers installed in your system, go to Control Panel -> Administrative Tools -> Data Sources (ODBC) -> Drivers. Note that our CSV file was in the C:\Temp folder. This path has to be visible to the server. In my case, on my laptop, it’s not a problem… my server is my machine. But if the server is on another machine somewhere out there on the network or in the cloud, then C:\Temp does not refer to a path on my local machine running SSMS, but to a path on that machine on which the server is installed. This is not a big problem, but it is something that you have to be aware of. But the name of that path can be a problem. Let’s say instead of putting the CSV file in the C:\Temp folder, we decide to put it into a folder called C:\CSV Files. If we try to execute that, here’s what happens: select TerritoryIDIt’s that darn space character embedded in the folder name that causes the problem. Even if we put double-quotes around the path and filename, it still doesn’t work, displaying a different error message: select TerritoryIDLuckily this problem can be overcome by removing the path from the filename and specifying it as the DefaultDir in the Provider String parameter (the second parameter) of OPENROWSET: select TerritoryIDWhat if the filename itself has a space in it? If we rename the file to Territory Data.CSV, then we have a problem again: select TerritoryIDBut this problem can be fixed by putting double quotes around the filename: select TerritoryIDBy the way, you may have noticed that the TerritoryID output above is right-justified in the output, indicating that the Text Driver made a “best guess” (based on the data it saw in the column) that the column was numeric. Sometimes you don’t want the Text Driver to assume anything about the column datatypes. For example, if you are importing a CSV file that has Zip Codes or Social Security Numbers, for example, you want those imported as character data, but the Text Driver will only see digits in its sampling and will insist on making it numeric data (thereby losing leading zeroes). You can get around this by creating a SCHEMA.INI file to describe the contents of your CSV files. You can read more about that here. Another problem with this OPENROWSET(‘MSDASQL’) approach is that it assumes the MSDASQL provider is installed. I naïvely thought that this was installed by default when SQL Server is installed. Apparently it’s not. And unfortunately, my client did NOT have this in his list of providers. To see which providers you have installed, go to the Object Explorer in SSMS and look under Server Objects -> Linked Servers -> Providers: ![]() Finally, the OPENROWSET command expects only string literals for its parameters, so you cannot attempt to use variables like so: declare @FilePath varchar(100) = 'C:\CSV Files\'So, if you have the Path and Filename in variables, the only way you can accomplish reading in that file’s data is via Dynamic SQL, like so: declare @FilePath varchar(100) = 'C:\CSV Files\'So, to recap, if you want to use the OPENROWSET(‘MSDASQL’) approach, use the following guidelines:
Since my client didn’t have the MSDASQL provider at all, I had to come up with a completely different approach to reading in the CSV file. |
手机版|BC Morning Website ( Best Deal Inc. 001 )
GMT-8, 2025-7-8 08:32 , Processed in 0.015964 second(s), 19 queries .
Supported by Best Deal Online X3.5
© 2001-2025 Discuz! Team.