Search This Blog

Monday, January 30, 2017

xp_fileexist And its Alternate

xp_fileexists is a very useful undocumented stored procedure of SQL Server.
The usage of xp_fileexist is as follow;
Exec xp_fileexist “E:\abc.txt”
The values returned are



You can also use OUTPUT parameter to get the value of “File Exists” column as below;

Declare @vFileExists int
exec master.dbo.xp_fileexist 'E:\abc.txt', @vFileExists OUTPUT
Select @vFileExists

If you want to save all three returned values, then you will have to go throu Temp Table approach;

Declare @vFileExists Table (FileExists int, FileDir int, ParentDirExists int)

insert into @vFileExists
       exec master.dbo.xp_fileexist 'E:\abc.txt'
Select * from @vFileExists




Sometimes xp_fileexist behaves abnormally. Your file is there and it does not check the file and returns 0 in FileExists column. This is an extended SP so its behavior may also change with different versions of SQL Server.
If you are facing the same problem, change you code with xp_cmdshell “dir” approach;

Declare @vExistsPath nvarchar(100)
Declare @files Table ([FileName] nvarchar(100))
Set @vExistsPath = ''
Set @vExistsPath = 'E:\abc.txt'
Set @vExistsPath = 'dir ' + @vExistsPath + ' /b'
Insert into @files EXEC xp_cmdshell @vExistsPath
Select * from @files
if Exists(Select 1 from @files where [FileName] = 'abc.txt' And [FileName] is Not Null)
begin
       Select 1
end
else
begin
       Select 0
end

The “/b” switch returns only filename with extension as a result of “dir” command





Handeling comma while creating CSV

I would recommend you should NOT use comma ',' in your csv as I think you are facing issues because of ',' in the data of your text column. Instead you can use '|' sign.
EXECUTE master.dbo.xp_cmdshell 'bcp "SELECT Column1, Column2, Column3 FROM YourDB.[dbo].[YourTable] ORDER BY 1" queryout E:\Objects3.txt -t"|" -c -T '
if you still want to use comma as separator due to any limitation, you can use char(34) before and after the column that you think may have comma in the text. Adding char(34) i.e. double quote, will make the text with comma as a single value.


EXECUTE master.dbo.xp_cmdshell 'bcp "SELECT Column1, char(34) + Column2 + char(34) , Column3 FROM YourDB.[dbo].[YourTable] ORDER BY 1" queryout E:\Objects3.txt -t"," -c -T '


The above code assumes that you have comma in Column 2 and file created is comma separated CSV.

I hope it will help you.

Monday, January 23, 2017

Microsoft.ACE.OLEDB.12.0 Issues and their solution

Few OLEDB issues that I would like to share;

1.       Msg 7415, Level 16, State 1, Line 1
Ad hoc access to OLE DB provider 'Microsoft.ACE.OLEDB.12.0' has been denied. You must access this provider through a linked server.

If you see this message with your OLEDB query, it means you do not have sufficient rights on the OLEDB source. Please check your user have enough rights to access the OLEDB provider. The provider must show in the list of providers as below;



Secondly, right click the provider and check “Disallow adhoc Access”. It should be unchecked.
               
2.       Msg 7302, Level 16, State 1, Line 1
Cannot create an instance of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".

Check the above issues stated in point 1. If above settings are good, and still getting this error, then it your syntax. Please check the correct syntax to query using the Provider. For example, to query excel file, the correct syntax is;

SELECT *
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0;Database=F:\FleName.xlsx',
                           'select * from [sheet1$]')

For csv, the syntax is;

SELECT *
               FROM OPENROWSET ('Microsoft.ACE.OLEDB.12.0',
                      'Text;Database=E:\',
                      'SELECT * from FileName.csv')
Please note that in case of excel, File name is give in the “Database” property and sheet name is given in the “Select * from [sheet1$]” statement.

In case of csv, only path is given for “Database” property and file name is given in the “Select * from Filaname.csv” part.


3.  OLE DB provider 'Microsoft.ACE.OLEDB.12.0' cannot be used for distributed queries because the provider is configured to run in single-threaded apartment mode.

You need to install 64 bit or 32 bit Access driver depending upon the operating system that you have on the machine where you are running the query to access the excel or csv file.


4.       Few columns returning NULL in the dataset
You might see this issue where your values are turning into NULL. If you look deeply into your data, you will notice that the values in the column are numbers (not alpha numeric charachters) and the values that are alpha numeric in the parent file are turning into NULL. This is because the data type of the column is determined based up on the first few data values in the column. If these are numbers, the datatype will be set to “int” and all character values will be saved as NULL.

To solve this issue, you need to do some changes in the registry as shown in the screen below;



Open registry of the server in which you are processing the csv / Excel file. Go to the following path;

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\Access Connectivity Engine\Engines\Text

We have selected “Text” as we faced this issue while processing CSV files.


Change “ImportMixedTypes” property value to “Text”. Save the registry. Execute the query again and you will now see all your data returning as Text. You can no move your data as per your table schema.