Today I use xp_read_file to see if a file exists or not. But on somtimes it return null even if a file exist?
I guess there's better way than do like this to check if a file exist or not? |
Just for completeness I'd like to add a further solution (although certainly not an "easy one", so I would prefer the directory access server for v12): You can also create an external (native) function that calls an OS-level function to check for an existing file, say for Windows to call the GetFileAttributes API. Breck has explained in his (former?) blog how to call a different WinAPI function (GetOpenFileName()) here: 1
Are you saying that doesn't pass the "something simpler" test? :)
(27 Jan '16, 08:10)
Breck Carter
|
SELECT 1 FROM sp_list_directory( '\\\\server10\\folder1\\' ) where file_path = '\\\\server10\\folder1\\test.log' Just to note: sp_list_directory() was introduced in v16.
(22 Jan '16, 16:44)
Volker Barth
|
I have this example that I use to check my backup logs:
After that, to check a file, you can just run a simple select:
Your directory will work like a table. You can select, update and delete files. It works for me. Thanks! But there must be something simpler way to do it?
(22 Jan '16, 11:10)
Rolle
Can I use this to include subfolders? Or Can I load two different folders to same table?
(25 Jan '16, 15:14)
Rolle
|
When you do use xp_read_file() - say, because you are not running v16 or above - you can set the optional 2nd "lazy" parameter to 1 or the like to prevent the file contents from being read. That should give a performance benefit particularly for larger files.
We use v12. What then is the best method to check if a file exists or not with that version. xp_read_file works fine, but many times it returns null even if it is a physical file on that path?
Sounds like a bug, unless perhaps it is returning null when the file is empty... " If the file does not exist or cannot be read, NULL is returned." - V16 Help
Strange. Is there a bugfix made between v12 and v16?
Note the "or cannot be read" part - possibly the according file is opened in exclusive mode?
E.g. trying to open the database's own translog will return NULL although it certainly exists at that time:
(And according to your sample, the same will be true if you try to open the log of another database...)
I do not quite understand what you mean. If I want to see if a file exists or not, whether it is open or not, what do I do? Your example only returns null for me.
If the files you are looking at may be open / locked you need to look at the other two solutions proposed below: ie a directory server, or simpler if you are using v16 / v17 sp_list_directory()
xp_read_file() does what it says - it reads the file. If the operating system won't let the database engine read the file, it can't read it and therefore can't return anything.
Also be aware that xp_read_file() by default reads the whole file, so if the files that you are interested in are very large, it could be slow and generate a lot of disk activity. It that case you can choose to read just one byte of the file with something like:
which will return just the first byte of the file - enough to know if there is something there!
Ok, I think the problem is that the operating system won't let the database engine read the file. There we have the answer! So, I use v12, is there any other way to look if a file exist or not?
Thiago's solution will work in v12 - see the docs on CREATE SERVER
http://dcx.sap.com/index.html#1201/en/dbreference/create-server-statement.html
If you don't want to do that for whatever reason I suggest you think about using a batch file with an construct like:
that set an error level accordingly and call that with xp_cmdshell() and look at the return values.
Big thanks! Something like this?
Returns 1 since goto error returns an error since error does not exist.
Returns 0 since c:\test.txt exists.
Regarding Thiago solution, I guess I should change this row to include subfolders
Doesn't cmdshell work on a network path? Locally on the C:\ it works for me, but when I try on a mapped drive, it will not work. Ex:
It depends on the rights of the user that the database engine runs under. The default system user won't have rights to network locations. You'll need to configure network rights appropriately whichever method you use.
Thanks for fast response!
Can you describe a little more how I should tell our IT provider how to configure the database engine so it get network rights?
You may have a look at that FAQ, both as to the background and possible solutions:
How do I execute a batch file using xp_cmdshell?
BTW: Is that the reason why xp_read_file() does fail for you - the engine is asked to read a file on a net share that it cannot access? Or is the file locked exclusively? What do you want to do with the file if it exists?