Export xlsx Files out of a SQL Server database - sql-server

I'm trying to save Excel files in my SQL Server database as BLOB and export them.
Importing the file was quiet easy, but when I'm trying to export them to the file system, the file is damaged and unreadable.
I was quite shocked, because I thought Microsoft wouldn't have much problems importing and exporting their own file types.
INSERT INTO TestBlob(tbName, tbDesc, tbBin)
SELECT
'testfile.xlsx', 'testfile', BulkColumn
FROM
OPENROWSET (Bulk 'C:\temp\testfile.xlsx', Single_Blob) AS tb
I already tried to export it by bcp but I just got a corrupted file.
Do I have to provide a special format file for xlsx files? Are there any other ways to get the xlsx files out of the database?
Thanks in advance
BR. RF

EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
GO
RECONFIGURE;
GO
USE [AdventureWorks];
GO
INSERT INTO OPENROWSET ('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=c:\contact.xls;',
'SELECT * FROM [Sheet1$]')
SELECT TOP 5 FirstName, LastName
FROM Person.Contact
GO
https://blog.sqlauthority.com/2008/01/08/sql-server-2005-export-data-from-sql-server-2005-to-microsoft-excel-datasheet/
Or . . .
1 Export data to existing EXCEL file from SQL Server table
insert into OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=D:\testing.xls;',
'SELECT * FROM [SheetName$]') select * from SQLServerTable
2 Export data from Excel to new SQL Server table
select *
into SQLServerTable FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=D:\testing.xls;HDR=YES',
'SELECT * FROM [Sheet1$]')
3 Export data from Excel to existing SQL Server table
Insert into SQLServerTable Select * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=D:\testing.xls;HDR=YES',
'SELECT * FROM [SheetName$]')
4 If you dont want to create an EXCEL file in advance and want to export data to it, use
EXEC sp_makewebtask
#outputfile = 'd:\testing.xls',
#query = 'Select * from Database_name..SQLServerTable',
#colheaders =1,
#FixedFont=0,#lastupdated=0,#resultstitle='Testing details'
(Now you can find the file with data in tabular format)
5 To export data to new EXCEL file with heading(column names), create the following procedure
create procedure proc_generate_excel_with_columns
(
#db_name varchar(100),
#table_name varchar(100),
#file_name varchar(100)
)
as
--Generate column names as a recordset
declare #columns varchar(8000), #sql varchar(8000), #data_file varchar(100)
select
#columns=coalesce(#columns+',','')+column_name+' as '+column_name
from
information_schema.columns
where
table_name=#table_name
select #columns=''''''+replace(replace(#columns,' as ',''''' as '),',',',''''')
--Create a dummy file to have actual data
select #data_file=substring(#file_name,1,len(#file_name)-charindex('\',reverse(#file_name)))+'\data_file.xls'
--Generate column names in the passed EXCEL file
set #sql='exec master..xp_cmdshell ''bcp " select * from (select '+#columns+') as t" queryout "'+#file_name+'" -c'''
exec(#sql)
--Generate data in the dummy file
set #sql='exec master..xp_cmdshell ''bcp "select * from '+#db_name+'..'+#table_name+'" queryout "'+#data_file+'" -c'''
exec(#sql)
--Copy dummy file to passed EXCEL file
set #sql= 'exec master..xp_cmdshell ''type '+#data_file+' >> "'+#file_name+'"'''
exec(#sql)
--Delete dummy file
set #sql= 'exec master..xp_cmdshell ''del '+#data_file+''''
exec(#sql)
After creating the procedure, execute it by supplying database name, table name and file path
EXEC proc_generate_excel_with_columns 'your dbname', 'your table name','your file path'
As an alternative, you could use "External data" from Excel. It can use ODBC connection to fetch data from external source: Data/Get External Data/New Database Query. That way, even if the data in the database changes, you can easily refresh.

Related

How to import data from excel file into sql server DB by script

I am trying to import data from Excel into SQL.
I saw all kinds of answers on Google, but I didn't really find the right answer
I would really appreciate any help on this matter...
I have an excel file in a folder and I want to create a script that will load all the data from this excel file into a dedicated table in my DB
The script should be written in SQL Server
Does anyone have a simple way to do this?
I try this code:
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO
USE Diyur;
GO
SELECT * INTO Data_dq
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=C:\File.xls', [Sheet1$]);
GO
But I get this error:
Msg 7403, Level 16, State 1, Line 12 The OLE DB provider
"Microsoft.ACE.OLEDB.12.0" has not been registered. Blockquote
After many google searches and my many attempts I found the correct code:
declare #SQL nvarchar(max) = '
CREATE TABLE #TempTable
( [Field1] nvarchar(max) NULL,
[Field2] nvarchar(max) NULL,
[Field3] nvarchar(max) NULL );
BULK INSERT #TempTable FROM ''<FullPath>\FileName.csv'' WITH --if the path is in the network - need to write the Full-path of the drive
(
KEEPIDENTITY,
FIELDTERMINATOR = '','',
MAXERRORS = 10000,
KEEPNULLS,
ROWTERMINATOR=''\n'',
FIRSTROW = 2,
CODEPAGE = ''1255''
);
select * from #TempTable
Insert into TableNameInDB(Field1,Field2,Field3)
select * from #TempTable
'
EXEC sp_executesql #SQL

SQL Server Filestream query for updating the filestream column using the file path column present in the table

I have a table in Microsoft SQL Server with file path, now I want to store the files as filestream data in the database.
I want to run a bulk update query to convert each row of the table to the corresponding filestream data using the filepath column.
Columns of my table are SrNo, FilePathLocation, FileStreamBlob, Key.
I am able to run the following query successfully for 1 row but I have over 500+ rows in the table with filepath can anyone please help me with the update query for updating all the rows of the table using the filepath column.
DECLARE #file_stream VARBINARY(MAX)
DECLARE #command nvarchar(1000)
DECLARE #filePath NVARCHAR(128)
SET #filePath = (SELECT FilePathLocation FROM ScanFileTable WHERE SrNo = 2077)
SET #command = N'SELECT #file_stream1 = CAST(bulkcolumn AS varbinary(MAX))
FROM OPENROWSET(BULK ''' + #filePath + ''', SINGLE_BLOB) ROW_SET'
EXEC sp_executesql #command, N'#file_stream1 VARBINARY(MAX) OUTPUT',#file_stream1 =#file_stream OUTPUT
UPDATE ScanFileTable
SET FileStreamBlob = #file_stream
WHERE SrNo = 2077

Why xp_cmdshell exports empty PDF files from database that stored in image datatype

I have query that extracts PDF files into directory. But for some reason all files are empty (0 KB).
Column PDF stored as image datatype. I know its obsolete but I am not the owner of the database.
Would you suggest any workaround?
CREATE TABLE #tblPolicyForms
(
FormID INT NOT NULL
,PDF varbinary(max) NULL
,PDF_FIlename VARCHAR(max)
)
INSERT INTO #tblPolicyForms
SELECT FormID,
PDF,
PDF_FileName
FROM [dbo].[tblPolicyForms]
WHERE FormID IN (19,20,21,22)
--select * from #tblPolicyForms
DECLARE #FormID varchar(4);
DECLARE #FileName VARCHAR(200);
DECLARE FormID_cursor CURSOR FOR
SELECT
FormID
,PDF_FIlename
FROM
#tblPolicyForms
WHERE FormID IN (19,20,21,22)
OPEN FormID_cursor
FETCH NEXT FROM FormID_cursor
INTO #FormID, #FileName
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #cmd VARCHAR(8000) = 'BCP "SELECT PDF FROM #tblPolicyForms " queryout "C:\Users\oserdyuk\Documents\ExportDir\'+#FileName+'" -T -N'
--print #cmd
EXEC master.dbo.xp_cmdshell #cmd;
FETCH NEXT FROM FormID_cursor
INTO #FormID, #FileName
END
CLOSE FormID_cursor
DEALLOCATE FormID_cursor
The thing is BCP is opening another connection to SQL Server, and regular temp tables like your #tblPolicyForms are private to the connection. The BCP is probably generating an error which you don't get to see.
Can you change your temp table to a global one? This way the other connection (BCP) will be able to access it. You need to use two pound signs like this:
CREATE TABLE ##tblPolicyForms
(
FormID INT NOT NULL
,PDF varbinary(max) NULL
,PDF_FIlename VARCHAR(max)
)
You also need to change every reference from #tblPolicyForms to ##tblPolicyForms (single to double pounds). Be aware that if the procedure is executed in parallel by different sessions you will receive an error indicating that ##tblPolicyForms already exists.
Another thing, you are exporting every row into every file, so every file ends up the same size as you have seen. You need a WHERE clause in your BCP like this:
DECLARE #cmd VARCHAR(8000) = 'BCP "SELECT PDF FROM ##tblPolicyForms WHERE FormID = ''' + #FormID + ''' " queryout "C:\Users\oserdyuk\Documents\ExportDir\'+#FileName+'" -T -N'
But even then things might not work properly because bcp will prepend a 8 byte header to your row. Since bcp is an export/import tool it will create a file it can later import back into your database.

Batch file to insert Excel data into SQL Server table

I'm trying to write a batch file that takes information from an Excel spreadsheet and adds new rows into my SQL Server.
I think what I have currently is nearly there. As it runs and says a line has been updated, but it hasn't.
This is my batch file:
#echo off
copy \\RDS-2012-C\2012_N_Drive\Operations\Reports\Metrics\sql2.xlsx C:\ACCESS_SQLSVR\import_location
sqlcmd -S RDS-2012-G\RDS_SQL -d Master -i C:\ACCESS_SQLSVR\import_location\sesame_import.sql
pause
And this is what it runs:
EXEC sp_configure 'Show Advanced Options', 1;
RECONFIGURE
GO
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE
GO
EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1;
GO
EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1;
GO
SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0;Database=C:\ACCESS_SQLSVR\import_location\sql2.xlsx;HDR=YES;IMEX=1',
'SELECT * FROM [SQL$]')
GO
Do I simply need a different command instead of SELECT?
Also, the full database and table in the SQL Server is called:
Sesame_FTest.dbo.SQL
Running this when the table doesn't exist results in the table being created and filled with the Excel information. But running it a second time with a new Excel doesn't update like I thought it would.
Try it like this . . .
------ INSERT INTO NON-EXISTING TABLES
USE [YourDatabase]
GO
SELECT * INTO tbl_Mapping
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0 Xml;HDR=YES;Database=C:\Users\rshuell001\Desktop\State Street\Final Deliverables\Raw Data\Mapping.xlsx',
'SELECT * FROM [Mapping$]')
SELECT * INTO tbl_Data
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0 Xml;HDR=YES;Database=C:\Users\rshuell001\Desktop\State Street\Final Deliverables\Raw Data\Data.xlsx',
'SELECT * FROM [Data$]')
OR . . .
------ INSERT INTO EXISTING TABLES
USE [YourDatabase]
GO
Insert INTO tbl_Mapping
SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0 Xml;HDR=YES;Database=C:\Users\rshuell001\Desktop\State Street\Final Deliverables\Raw Data\Mapping.xlsx',
'SELECT * FROM [Mapping$]')
Insert INTO tbl_Data
SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0 Xml;HDR=YES;Database=C:\Users\rshuell001\Desktop\State Street\Final Deliverables\Raw Data\Data.xlsx',
'SELECT * FROM [Data$]')

Find All Empty Tables Named MAP_ALERT In All Databases On Server

We perform studies at my job, and each study has its own database. All the study databases are on the same server, and eaxch has a table named MAP_ALERT.
I need to find all MAP_ALERT tables that contain no data, for all the study databases. I found this page that tells how to find empty tables in one database: Select all empty tables in SQL Server - how can I adapt this to find ALL empty tables named MAP_ALERT in ALL database on a given server?
You can use dynamic sql here to help you out. This is querying the system tables for each database. This will even properly handle databases that don't have that table.
declare #SQL nvarchar(MAX)
set #SQL = '';
create table #Results
(
DBName sysname
)
select #SQL = #SQL + 'if exists(select * from ' + name + '.sys.tables where name = ''MAP_ALERT'') insert #results (DBNAME) select ''' + name + ''' from ' + name + '.dbo.MAP_ALERT having count(*) > 0;'
from sys.databases
--select #SQL
--uncomment the following when you have evaluated the dynamic sql and understand what query is going to run on your system
exec sp_executesql #SQL
select * from #Results

Resources