Reputation: 2053
I am trying to export the data from sql server tables to a csv file without ssms.
i am trying to achieve it by creating a stored procedure using bcp.
declare @sql nvarchar(4000);
select @sql = 'bcp "select * from table" queryout c:\file.csv -c -t, -T -S'+ @@servername
exec xp_cmdshell @sql
1 ) This query produces the expected results. But what i want is it should also include the column names in the csv files. So how can i achieve that ?
2) I want this result for all the tables in the given database. So how to do that ?
Please give some suggestions or solution as soon as possible
thanks
Upvotes: 0
Views: 14010
Reputation: 866
Try this code if you want column name with SQL table data :-
public void ExportExcelFileToFolder()
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM MachineMaster"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt, "SheetName");
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=SqlExport.xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
string fileName = Guid.NewGuid() + ".xlsx";
string filePath = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/ExeclFiles"), fileName);
MyMemoryStream.WriteTo(new FileStream(filePath, FileMode.Create));
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
}
}
}
}
}
}
Upvotes: 0
Reputation: 1802
I would suggest doing something along the lines of:
@echo off
bcp "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table_name>' AND TABLE_SCHEMA='<table_schema>'" queryout c:\file.csv -c -r, -T -S <server_name> -d <database_name>
bcp "select * from <table_schema>.<table_name>" queryout c:\data.csv -c -t, -T -S <server_name> -d <database_name>
echo. >> c:\file.csv
type c:\data.csv >> c:\file.csv
del c:\data.csv
in a .bat
file.
I think that for what you want to do, it's better to just use the bcp
command from a batch file/command line, instead of enabling the xp_cmdshell
in SQL Server which could introduce a security issue.
Additionally, I'd like to point out that I'm not sure if the columns will always come out in the same order (in my case it did).
EDIT: Batch file explanation.
I basically ran 2 bcp
commands and sent the output to 2 different files, as I couldn't find an option to append the output to another file. I then merely used the type
command to add the data to the file already containing the column list, and deleted the file with the data as it is no longer needed.
Feel free to modify and mess around with it and let me know if you run into any problems.
Upvotes: 0
Reputation: 7616
Only workarounds I know of...
Query the data dictionary and produce a csv field list, then concatenate the header.csv with the data.csv. This would be querying the columns table, but you would need to take care to generate the SQL to match since you want to remove any and all chances that the column list doesn't match the data.
Create a view with the first row having all field names union all
with a select on the data.
Something like:
SELECT 'a', 'b', 'c' UNION ALL SELECT a, b, c FROM table
This may require type conversions for dates, though.
Upvotes: 0