Using openrowset, I am loading the XML file to a temp table.
How do I get the file created date?
CREATE TABLE #T
(
IntCol int,
XmlCol xml
);
INSERT INTO #T (XmlCol)
SELECT *
FROM OPENROWSET(BULK 'c:\Test.xml', SINGLE_BLOB) AS x;
SELECT * FROM #t
Not the most concise way to do this, but using Ole Automation in SQL Server is one way to get this information. The following sample uses C:\Temp\testfile.txt as an example. This not really "SQL", don't know if this good enough for you.
DECLARE #hr INT;
DECLARE #dt_created DATETIME;
DECLARE #obj_file INT;
DECLARE #obj_file_system INT;
DECLARE #file_name VARCHAR(100)='C:\Temp\testfile.txt';
-- Create a FileSystemObject. Create this once for all subsequent file manipulation. Don't forget to destroy this object once you're done with file manipulation (cf cleanup)
EXEC #hr = sp_OACreate 'Scripting.FileSystemObject', #obj_file_system OUT;
IF #hr<>0 GOTO __cleanup;
-- Get a handle for the file. Don't forget to release the handle for each file you get a handle for (see cleanup). The return will be different from 0 if the file doesn't exist
EXEC #hr = sp_OAMethod #obj_file_system, 'GetFile', #obj_file out, #file_name;
IF #hr<>0 GOTO __print_created_date;
-- Retrieve the created date.
EXEC sp_OAGetProperty #obj_file, 'DateCreated', #dt_created OUT;
__print_created_date:
SELECT #dt_created AS file_date;
__cleanup:
EXEC sp_OADestroy #obj_file_system;
EXEC sp_OADestroy #obj_file;
Ole Automation needs to be enabled first though (just once):
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
T-SQL is not a language with which you can access file systems. However you can write a stored procedure in C# to accomplish this task. You would read the metadata with the appropriate classes in the .Net Framework. You can write a custom function with CLR integration to get every information you need from your filesystem.
Here is a little working sample to get an file created date with CLR integration in C#:
public class UserDefinedFunctions
{
[SqlFunction]
public static SqlDateTime GetCreatedDate(SqlString filePath)
{
return filePath.IsNull ? SqlDateTime.Null : File.GetCreationTime(filePath.Value);
}
}
Then you've got to deploy the assembly and register it to SQL Server, then create the proper function with Create function commands.
see more in CodeProject Sample
declare #f varchar(1000)='E:\work\share\data.txt';
declare #cmd varchar(1000)='for %a in ('+#f+') do echo %~ta'
IF OBJECT_ID('tempdb..#t1') IS NOT NULL
DROP TABLE #t1
create table #t1(_output varchar(1000))
insert #t1
exec xp_cmdshell #cmd
declare #fileDate varchar(100)
set #fileDate=(select _output from #t1 where _output not like '%echo%')
print #fileDate
and convert #fileDate to dateTime by your settings
Related
I am trying 30 days free trial of Chilkat and I am not getting any results in SQL, nor error information (unless it is a string text value, hardcoded). I have installed the module on the server and it confirms correctly
For example this piece of code with obviously incorrect address just runs through without any feedback (the code is from their tutorial - apart from the address - so should be technically correct)
DECLARE #hr int
DECLARE #iTmp0 int
DECLARE #sTmp0 nvarchar(max)
DECLARE #rest int
EXEC #hr = sp_OACreate 'Chilkat_9_5_0.Rest', #rest OUT
IF #hr <> 0
BEGIN
PRINT 'Failed to create ActiveX component'
RETURN
END
-- Connect to the REST server.
DECLARE #bTls int
SELECT #bTls = 1
DECLARE #port int
SELECT #port = 443
DECLARE #bAutoReconnect int
SELECT #bAutoReconnect = 1
DECLARE #success int
EXEC sp_OAMethod #rest, 'Connect', #success OUT, 'www.incorrect_address.co', #port, #bTls, #bAutoReconnect
IF #success <> 1
BEGIN
EXEC sp_OAGetProperty #rest, 'LastErrorText', #sTmp0 OUT
PRINT #sTmp0
EXEC #hr = sp_OADestroy #rest
RETURN
END
the Global Unlock method returns message that it is working
'Unlocked in trial mode.'
do you have any idea why it does not work? Any messages hardcoded (like 'unlocked in trial mode') are working but anything that should return values of objects - does not. I have of course enabled Configuration option 'Ole Automation Procedures' in SQL
Slav
The contents of the LastErrorText property is likely too large for limits imposed by sp_OAGetProperty. Try using a temp table like this:
DECLARE #tmp1 TABLE (lastErrText ntext)
INSERT INTO #tmp1 EXEC sp_OAGetProperty #rest, 'LastErrorText'
SELECT * from #tmp1
I am using SQL Server 2017 Express edition on Microsoft Windows 10. I want to import all text files in a directory into a database at one time. My idea is that that SQL Server loops over the files in that directory and imports them all at the same time. Is there a way that I can achieve this?
Best Regards,
declare #dir varchar(1000) = 'C:\Temp';
declare #command varchar(1000);
declare #files table (id int identity, filename varchar(1000));
set #command = 'dir /b ' + #dir;
insert into #files execute xp_cmdshell #command;
declare commands cursor for
select 'bulk insert <your table name here> from ''' + #dir + '\' + filename + ''' <other options, WITH FORMAT, etc. here>;' from #files;
open commands;
fetch commands into #command;
while (##fetch_status = 0) begin
--print #command;
execute(#command);
fetch commands into #command;
end;
close commands;
deallocate commands;
Modify #dir and the bulk insert command that is being build and you're done.
You may have to enable 'xp_cmdshell', and this could be a problem for your DBA; and using 'execute' is always a potential issue (SQL injection, etc.).
To enable xp_cmdshell:
-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1;
GO
-- To update the currently configured value for advanced options.
RECONFIGURE;
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1;
GO
-- To update the currently configured value for this feature.
RECONFIGURE;
GO
As noted in another answer, xp_commandshell is problematic. SQL Server 2016+ allows another approach. See example
declare #tbl table(fn varchar(255), depth int,[isfile] int,primary key(fn))
declare #dir varchar(50)='C:\temp\' --'starting dir
insert #tbl
EXEC Master.dbo.xp_DirTree #dir,1,1 --dir, depth (1 - current only), file (0 - dirs only, 1+ - dirs and files)
delete #tbl where [isfile]=0 or fn not like '%.txt' --keep .txt files only
--select * from #tbl
--will insert into this table
create table #fileTbl (id int identity(1,1) primary key,fn varchar(255),txt varchar(max))
declare #fn varchar(255), #query nvarchar(4000)
select top 1 #fn=fn from #tbl
while ##ROWCOUNT>0--number of rows from the last query executed
begin
--dynamic query required to build OPENROWSET
set #query='insert #fileTbl(fn,txt) select '''+#dir+#fn+''',BulkColumn from openrowset(bulk ''c:\temp\'+#fn+''',single_blob) t'
exec sp_executesql #query
delete #tbl where fn=#fn
select top 1 #fn=fn from #tbl --proceed
end
select * from #fileTbl
I an a bit amateur and I need to have my webservice called in sp so that I can give it an input right in sp and obtain the output but my sql code makes an error :sp_OACreate has not yet been called successfully for this command batch.
what is the solution? could anybody tell me simply?
I use sqlserver2012
and my sp is like:
create procedure [dbo].[test2]
#paramd int,
#paramm int,
#paramy int
as
begin
declare #obj int
declare #sUrl nvarchar(max)
declare #response varchar(8000)
declare #xml XML
set #sUrl= 'http://localhost:31876/myage/WebService.asmx?op=converttodaysweb?day:'+convert(nvarchar,#paramd)+'month:'+convert(nvarchar,#paramm)+'year:'+convert(nvarchar,#paramy)
exec sys.sp_OAMethod #obj,'Open',null,'GET',#sUrl,false
exec sys.sp_OAMethod #obj,send,null,''
exec sys.sp_OAGetProperty #obj,'responseXML.xml',#response OUT
SELECT #response [response]
exec sys.sp_OADestroy #obj
RETURN
END
I have read some arts about BCP or CLR code that will export BLOBs to individual files on the hard drive, but I need to BCP or CLR out the entire table data together (meaning the other columns which are character or integer or datetime data need to come out as a whole) I need to make sure I can BCP/CLR the data back into the table and have the same linking between BLOBs and other column data.
Any ideas?
I'm not sure if I understand what you're asking, so I'll try to cover two cases.
First, if you'd like to export all your data (including varbinary blobs) into one file, you can do it. Here's a test script to use with your table. You have to turn on SQLCMD mode in your SSMS. Then issue this script:
-- create target structure same as source
select top 0 *
into YourTbl2
from YourTbl
-- first line makes BCP dump to file, second line imports it to target structure
!!bcp YourDb.dbo.YourTbl out "D:\Temp\BlobTest.bak" -T -c
!!bcp YourDb.dbo.YourTbl2 in "D:\Temp\BlobTest.bak" -T -c
-- test if everything is imported
select * from Playground.dbo.BlobTest
except
select * from Playground.dbo.BlobTest2
If you want to just export an individual file to disk where your SQL Server resides, you can use this:
!!bcp "SELECT TOP 1 YourBlob FROM YourDb.dbo.YourTbl" queryout "D:\Temp\YourFile.xyz" -T -c
If it's applicable, you can share the folder where you're exporting your blob and access it from your client PC.
You can do like the Following :
You can have Image Data Type to Hold Any Files with in.
And, Please Read the Following Thoroughly to Understand.
I've implemented this in our Project. Simple and Fully Dynamic.
You just have to call :
Insert [tblTemp] (imageType,ImageFile) Select '.PDF',BulkColumn from Openrowset( Bulk 'C:\mak\A.PDF', Single_Blob) as tb
to Insert into the Table and
You can Use :
WriteBinaryToDisc 'C:\NEWF\','MAK','.PDF','DOC_TABLE','DOC_ID','DOC_IMAGE','WHERE DOC_ID=''25'''
to write back to the File System with Your specified Location and Extension.
I've used an tblTemp to hold all the Files.
--FIRST CHANGE THE CONFIGURATION TO ACTIVATE THIS FEATURE
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'Ole Automation Procedures';
GO
--HOW TO WRITE FILES TO DIRECTLY SQL SERVER FROM DISC
CREATE TABLE [dbo].[tblTemp](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ImageType] [varchar] (10) NULL,
[ImageFile] [image] NULL
) ON [PRIMARY]
Insert [tblTemp] (imageType,ImageFile) Select '.PDF',BulkColumn from Openrowset( Bulk 'C:\mak\A.PDF', Single_Blob) as tb
-----------------------------------------------------
--HOW TO WRITE FILE TO DISC FROM SQL SERVER
--WriteBinaryToDisc 'C:\NEWF\','MAK','.PDF','DOC_TABLE','DOC_ID','DOC_IMAGE','WHERE DOC_ID=''25'''
ALTER PROCEDURE WriteBinaryToDisc
(
#Path VARCHAR(255),
#Filename VARCHAR(100),
#FileExt VARCHAR(4),
#TblName varchar(50),
#IDField VARCHAR(50),
#ImageField VARCHAR(50),
#WHERE VARCHAR(300)
)
AS
set nocount on
EXEC ('
DECLARE #SOURCEPATH VARBINARY(MAX),
#DESTPATH VARCHAR(MAX),
#ObjectToken INT,
#image_ID BIGINT
DECLARE IMGPATH CURSOR FAST_FORWARD FOR SELECT '+#ImageField+','+#IDField+' from '+#TblName+' '+#WHERE+'
OPEN IMGPATH
FETCH NEXT FROM IMGPATH INTO #SOURCEPATH, #image_ID
WHILE ##FETCH_STATUS = 0
BEGIN
SET #DESTPATH = '''+#Path+'\'+#Filename+'''+ CAST(#image_ID AS varchar)+'''+#FileExt+'''
EXEC sp_OACreate ''ADODB.Stream'', #ObjectToken OUTPUT
EXEC sp_OASetProperty #ObjectToken, ''Type'', 1
EXEC sp_OAMethod #ObjectToken, ''Open''
EXEC sp_OAMethod #ObjectToken, ''Write'', NULL, #SOURCEPATH
EXEC sp_OAMethod #ObjectToken, ''SaveToFile'', NULL, #DESTPATH, 2
EXEC sp_OAMethod #ObjectToken, ''Close''
EXEC sp_OADestroy #ObjectToken
FETCH NEXT FROM IMGPATH INTO #SOURCEPATH, #image_ID
END
CLOSE IMGPATH
DEALLOCATE IMGPATH
')
---------------------------------------------------------------
I'm currently tasked with reading some data that stored in a flat file into my database and run reports against it. The one problem I'm running into is checking to see if a file actually exists. Is there a simple function to check if the file exists?
Thanks!
Just googling I found this at SQL DBA and this at MS SQL tips.
You are doing ETL in a stored procedure?!! I don't think you should, just because you can.
I recommend you use use SSIS for this. Doing ETL in Stored Proc or TSQL is not a recommended practice, in fact, it is frequently used as an example of what not to do.
I believe you can do something like this:
DECLARE #Path varchar(128) ,
#FileName varchar(128)
SET #Path = 'C:\'
SET #FileName = 'FILE_NAME.EXT'
DECLARE #objFSys int
DECLARE #i int
DECLARE #File varchar(1000)
SET #File = #Path + #FileName
EXEC sp_OACreate 'Scripting.FileSystemObject', #objFSys out
EXEC sp_OAMethod #objFSys, 'FileExists', #i out, #File
IF #i = 1
PRINT 'file exists'
ELSE
PRINT 'file does not exists'
EXEC sp_OADestroy #objFSys
This article goes over this method and a couple others.