vb.net get result of sql statement - vb.net

Hello take a look at the code below:
Try
con.ConnectionString = strCon
Dim strCommand as String = "RESTORE FILELISTONLY
FROM DISK = 'C:\AdventureWorks.BAK'
WITH FILE = 1
GO"
Dim cm As New SqlClient.SqlCommand(strCommand, con)
con.Open()
cm.ExecuteNonQuery()
Does anyone know how to get the list of logical files for my database, it does not work with executereader. i want to get the mdf and ldf files name for my database backup file.
Thanks.

As I've said before - the GO is NOT a T-SQL keyword - drop that!
And secondly, you don't need a WITH FILE when restoring only the file headers - try this:
Dim strCommand as String = "RESTORE FILELISTONLY
FROM DISK = 'C:\AdventureWorks.BAK'"
This will return several pieces of data - so you need to deal with a result set and thus use .ExecuteReader() to get this data from the query.
Try this code (it's C#, but should be easy enough to convert to VB.NET):
using System;
using System.Data;
using System.Data.SqlClient;
namespace GetPhysicalDbNames
{
class Program
{
static void Main(string[] args)
{
string stmt = #"RESTORE FILELISTONLY FROM DISK = 'D:\temp\AW2012.BAK'";
using (SqlConnection conn = new SqlConnection("server=.;database=master;integrated Security=SSPI"))
using (SqlCommand cmd = new SqlCommand(stmt, conn))
{
DataTable tblInfo = new DataTable();
SqlDataAdapter dap = new SqlDataAdapter(cmd);
dap.Fill(tblInfo);
foreach (DataRow row in tblInfo.Rows)
{
Console.WriteLine("Logical name: {0}", row["LogicalName"]);
Console.WriteLine("Physical file name: {0}", row["PhysicalName"]);
}
}
}
}
}
Executing that RESTORE command returns a result set, which contains among other two columns LogicalName and PhysicalName (which is the actual, complete physical file name of the .mdf and .ldf files)

Related

Can I store difference file types into SQL Server database?

I have created a vb.net project and a SQL Server database, I want to store my other created projects to the database with some of there description. I don't know can I do that or I can store my projects files into the database in the first place. I wanted to compress my projects files to a zip file and then store the zip file to the database but I don't know if I can store these files to the database which includes a lot of file types like (jar, java, sln, vb, c#, txt ...etc)?
Thanks for your help.
Yes, you can store files in a SQL Server database table. I highly recommend you to compress them into a zip file.
First step is to create a table:
CREATE TABLE Files
(
Id INT IDENTITY PRIMARY KEY,
FileData VARBINARY(MAX) FILESTREAM NULL,
Name NVARCHAR(300)
)
and then open your zip file as stream and Insert it into your table.
OpenFileDialog openFileDlg = new OpenFileDialog();
openFileDlg.InitialDirectory = Directory.GetCurrentDirectory();
if (openFileDlg.ShowDialog() == DialogResult.OK)
{
FileInfo fi = new FileInfo(openFileDlg.FileName);
FileStream fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read);
BinaryReader rdr = new BinaryReader(fs);
byte[] fileData = rdr.ReadBytes((int)fs.Length);
rdr.Close();
fs.Close();
string cs = #"Data Source=<your server>;Initial Catalog=MyFsDb;Integrated Security=TRUE";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
string sql = "INSERT INTO Files VALUES (#Data, #Name)";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.Add("#Data", SqlDbType.Image, fileData.Length).Value = fileData;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = fi.Name;
cmd.ExecuteNonQuery();
con.Close();
}
MessageBox.Show(fi.FullName, "File Inserted!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Source : MSDN

How to save the SQL Server table xml column data in physical path as .xml format?

I have an sql server database table which has xml column name called "MESSAGE" and which will store xml data.
The database table look like,
Now I need to get this "MESSAGE" column data and save into System physical path as xml file(Ex: test.xml etc.,)
Any suggestion how to implement this using c#.net?
You could try something like this (using plain ADO.NET and a very basic SQL query):
static void Main(string[] args)
{
// get connection string from app./web.config
string connectionString = "server=.;database=yourDB;Integrated Security=SSPI;";
// define query
string query = "SELECT MESSAGE FROM dbo.SamTest WHERE ID = 1;";
// set up connection and command
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand selectCmd = new SqlCommand(query, conn))
{
// open connection, execute query to get XML, close connection
conn.Open();
string xmlContents = selectCmd.ExecuteScalar().ToString();
conn.Close();
// define target file name
string targetFileName = #"C:\tmp\test.xml";
// write XML out to file
File.WriteAllText(targetFileName, xmlContents);
}
}

Sql Bulk Copy Cannot access destination table

I'm trying to read data from files and to use bulk copy to insert it in the database table.
When I try to run my code, I get the error: "Cannot Access Denstination Table"
Declaration of FlatTable.
System.Data.DataTable flatTableTempData = new System.Data.DataTable("FlatTable");
DataColumn DistrictColumn = new DataColumn();
DistrictColumn.ColumnName = "DistrictName";
// Create Column 3: TotalSales
DataColumn TownColumn = new DataColumn();
TownColumn.ColumnName = "TownName";
DataColumn FarmerColumn = new DataColumn();
FarmerColumn.ColumnName = "FarmerName";
flatTableTempData.Columns.Add(DistrictColumn);
flatTableTempData.Columns.Add(TownColumn);
flatTableTempData.Columns.Add(FarmerColumn);
This is my code, with the connection string and the insertion using bulk copy:
using (SqlConnection con = new SqlConnection("Data Source=DRTARIQ-PC\\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=TestDB2"))
{
con.Open();
using (SqlBulkCopy s = new SqlBulkCopy(con))
{
s.DestinationTableName = flatTableTempData.TableName;
foreach (var column in flatTableTempData.Columns)
s.ColumnMappings.Add(column.ToString(), column.ToString());
s.BulkCopyTimeout = 500;
s.WriteToServer(flatTableTempData);
}
}
I've encountered the same problem. The table exists, the SQL user has access but SqlBulkCopy cannot access the table. My problem turned out to be I turned off the indexing to try and insert faster (rebuild index after the bulkcopy), but this made the table inaccessible. After I turned the indexing on again it worked, SqlBulkCopy has access to the table.
The table name in WriteToServer method of SqlBulkCopy must be surrounded with [ ] signs.

Oledb behaves differently for .Net 4.0 and .net Framework Client Profile 4.0

Case1 :
When reading an excel using Oledb in .Net Framework Client Profile, the Oledb reads the data in excel ignoring the formatting that is given in excel
Example: 1.98782637 is actual value but after formatting it is displayed as 1.99.
When I read from my code the value that is read is 1.98782637.
Case2 :
When reading an excel using Oledb in .Net Framework, the Oledb reads the data which is available in excel after formatting
Example: 1.98782637 is actual value but after formatting it is displayed as 1.99.
When I read from my code the value that is read is 1.99.
Here is the code which I used for both the cases.
DataSet dsoutlier = null;
OleDbDataAdapter oledbAdapterOutlier = null;
OleDbConnection oledbConnOutlier = new OleDbConnection();
string fileName = "C:\\Sample.xlsx";
oledbConnOutlier.ConnectionString= "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";Extended Properties='Excel 12.0 Xml;HDR=NO;IMEX=0;\'";
if (oledbConnOutlier.State == ConnectionState.Closed)
oledbConnOutlier.Open();
oledbAdapterOutlier = new OleDbDataAdapter("select F1,F9 from [Sheet1$] where F1 is not null", oledbConnOutlier);
dsoutlier = new DataSet();
try
{
oledbAdapterOutlier.Fill(dsoutlier);
int counter = 0;
foreach (var item in dsoutlier.Tables[0].Rows)
{
Console.Write(dsoutlier.Tables[0].Rows[counter][0]+" ");
Console.WriteLine(dsoutlier.Tables[0].Rows[counter++][1]);
}
}
catch (Exception ex)
{
}
finally
{
oledbConnOutlier.Close();
}
Is there a way to include and ignore formatting in both the cases ?

Efficient way of uploading xls records to DB

What would be the most efficient way to upload records from an excel file to a table in the database. I am not allowed to use DTS/ SSIS. So I would like to know if there is a better alternative than reading records sequentially from the file and firing commands.
Thanks.
You could use the bcp utility. Save the Excel file as text and bcp it in. You don't usually need bulk insert privileges to do that.
Do you have permissions for bulk inserting?
This page has code that does the opposite - extract data from SQL Server and insert it into Excel. All you need to do is swap the connection strings.
Like this:
private System.Data.OleDb.OleDbDataAdapter da ;
private System.Data.DataSet ds;
string sqlSelect="SELECT ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, GETDATE() as TimeExtracted from Products order by UnitPrice";
string sqlInsert="INSERT INTO Foo (ProductId, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, TimeExtracted) VALUES (#ProductId, #ProductName, #QuantityPerUnit, #UnitPrice, #UnitsInStock, #TimeExtracted)";
string ExtractedTableName= "ExtractedData";
private void ReadFromSource()
{
System.Console.WriteLine("Reading from Source...");
string ConnStringSource=
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + ExcelFilename + ";" +
"Extended Properties=\"Excel 8.0;HDR=yes;\""; // FIRSTROWHASNAMES=1;READONLY=false\"
using (var conn= new System.Data.OleDb.OleDbConnection(ConnStringSource))
{
da= new System.Data.OleDb.OleDbDataAdapter();
da.SelectCommand= new System.Data.OleDb.OleDbCommand(sqlSelect);
da.SelectCommand.Connection= conn;
// this tells the DA to mark all rows as newly inserted.
// upon calling da.Update() (later), all those rows will
// be inserted into the DB.
da.AcceptChangesDuringFill= false;
ds= new System.Data.DataSet();
da.Fill(ds, ExtractedTableName);
}
}
private void InsertIntoDestination()
{
System.Console.WriteLine("Inserting data into Destination...");
string ConnStringDest= "Provider=sqloledb;Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;";
using (var conn= new System.Data.OleDb.OleDbConnection(ConnStringDest))
{
System.Data.OleDb.OleDbCommand cmd= new System.Data.OleDb.OleDbCommand(sqlInsert);
cmd.Parameters.Add("#ProductId", System.Data.OleDb.OleDbType.Integer, 4, "ProductId");
cmd.Parameters.Add("#ProductName", System.Data.OleDb.OleDbType.VarWChar, 40, "ProductName");
cmd.Parameters.Add("#QuantityPerUnit", System.Data.OleDb.OleDbType.VarWChar, 20, "QuantityPerUnit");
cmd.Parameters.Add("#UnitPrice", System.Data.OleDb.OleDbType.Currency, 8, "UnitPrice");
cmd.Parameters.Add("#UnitsInStock", System.Data.OleDb.OleDbType.SmallInt, 2, "UnitsInStock");
cmd.Parameters.Add("#TimeExtracted", System.Data.OleDb.OleDbType.Date, 8, "TimeExtracted");
da.InsertCommand= cmd;
da.InsertCommand.Connection= conn;
da.Update(ds, ExtractedTableName);
// in the event you want to update a datasource via a different DataAdapter --
// for example you want to fill from a System.Data.SqlClient.DataAdapter and
// then Update via a System.Data.Oledb.OledbDataAdapter -- then you could define
// two distinct DataAdapters. Fill the DataSet with the first DA, then Update
// with the second DA.
}
}
I suggest you connect to the excel file using ODBC/DSN through an ADODB connection.
I have found that this is pretty efficient.
You first create an ODBC Data source name thro: Control Panel>Administrative Tools> Data sources (ODBC). Select the 'System' tab and click 'Add'. Select 'Microsoft Excel driver' from the list of drivers that appears. Give your DSN a name say 'MYDB', then navigate the xlS file and double click to select.
This can be done programatically, its just that we created a dll to do it like 5 years ago and Im still trying to locate its source code. I will post its code as soon as I get it.
Then from your program you can connect to your DSN as follows:
'declare the connection
Global MyConn As New ADODB.Connection
'open the connection
MyConn.Open "DSN=MYDB;pwd=;"
You can then manipulate the connection through ADODB recordsets in the normal way.
I hope this helps