I have been using SMO for a while for transfering databases. It was pretty easy to handle from c# by using the TransferDatabase task.
For my current project this gets to slow. I have to switch to offline mode, where the database is detached and atached.
What is the least troublesome way to start such a process from c#? I know that there is SSIS, but if possible I would not like to use it. Installing SSIS on my machine is a bit painfull.
Just issue the SQL Server Detach and Attach command from c#
Something like this...
var sourceConnectionString = "Data Source=sourceServer;Initial Catalog=MyDB;Integrated Security=True;";
var destinationConnectionString = "Data Source=destinationServer;Initial Catalog=MyDB;Integrated Security=True;";
var sourceLocalPath = #"C:\MSSQL\DATA\MyDB.mdf";
var destinationLocalPath = #"C:\MSSQL\DATA\MyDB.mdf";
var sourceRemotePath = #"\\ServerNameA\ShareName\MyDB.mdf";
var destinationRemotePath = #"\\ServerNameB\ShareName\MyDB.mdf";
// Make connections
var sourceConnection = new SqlConnection(sourceConnectionString);
sourceConnection.Open();
var destinationConnection = new SqlConnection(destinationConnectionString);
destinationConnection.Open();
// Detach source database
var sourceCommand = new SqlCommand("sp_detach_db MyDB", sourceConnection);
sourceCommand.ExecuteNonQuery();
// Detach destination database
var destinationCommand = new SqlCommand("sp_detach_db MyDB", destinationConnection);
destinationCommand.ExecuteNonQuery();
// Copy database file
File.Copy(sourceRemotePath, destinationRemotePath);
// Re-attach source database
sourceCommand = new SqlCommand("CREATE DATABASE MyDbName ON (FILENAME = '" + sourceLocalPath + "') FOR ATTACH", sourceConnection);
sourceCommand.ExecuteNonQuery();
// Re-attach destination database
destinationCommand = new SqlCommand("CREATE DATABASE MyDbName ON (FILENAME = '" + destinationLocalPath + "') FOR ATTACH", destinationConnection);
destinationCommand.ExecuteNonQuery();
I do this work in my project.
you can use SqlBulkCopy class in C#. this class is very powerful and you can copy all of data with best performance.
this class make a bcp command and run it on your server. this commands are like this:
bcp pubs.dbo.authors out c: emppubauthors.bcp –n –Sstevenw –Usa –P
bcp pubs2.dbo.authors in c: emppubauthors.bcp –n –Sstevenw –Usa –P
there is many switches for this command. please see this code:
// Create source connection
SqlConnection source = new SqlConnection(connectionString);
// Create destination connection
SqlConnection destination = new SqlConnection(connectionString);
// Clean up destination table. Your destination database must have the
// table with schema which you are copying data to.
// Before executing this code, you must create a table BulkDataTable
// in your database where you are trying to copy data to.
SqlCommand cmd = new SqlCommand("DELETE FROM BulkDataTable", destination);
// Open source and destination connections.
source.Open();
destination.Open();
cmd.ExecuteNonQuery();
// Select data from Products table
cmd = new SqlCommand("SELECT * FROM Products", source);
// Execute reader
SqlDataReader reader = cmd.ExecuteReader();
// Create SqlBulkCopy
SqlBulkCopy bulkData = new SqlBulkCopy(destination);
// Set destination table name
bulkData.DestinationTableName = "BulkDataTable";
// Write data
bulkData.WriteToServer(reader);
// Close objects
bulkData.Close();
destination.Close();
source.Close();
Related
I can ATTACH database and copy all the data from one database to another.But on the end i can't detach it using same code.
var connection = new SQLiteConnection(connection)
connection.Open();
sqlAttachCommand = "ATTACH database '" + fileLoc + "' AS toMerge";
var cmd= new SQLiteCommand(sqlAttachCommand);
cmd.Connection = connection;
cmd.ExecuteNonQuery();
...
sqlAttachCommand = "DETACH database '" + fileLoc + "'";
The exception is:
SQL logic error or missing database no such database: C:\temp\database.db".
This is strange because I did attach for it and I did copy of all the data from this database.
The DETACH DATABASE command takes a schema-name as parameter, not a database file.
So your detach command should be like this:
sqlAttachCommand = "DETACH database toMerge";
as in your ATTACH command you named the thing toMerge.
In the SQL Exception the missing database isn't referring to the fact that SQLite lost that file, it is mere trying to tell that you're using a schema-name that doesn't exist.
I tried to create a shareable in-memory database as per the documentation provided on SQLite Site. But I end up finding the solution to the problem.
var connectionString = "Data Source=sharedmemdb;Mode=Memory;Cache=Shared";
using (var connection1 = new SQLiteConnection(connectionString))
{
connection1.Open();
var command1 = connection1.CreateCommand();
command1.CommandText =
"CREATE TABLE Message ( Text TEXT );" +
"INSERT INTO Message ( Text ) VALUES ( 'Is there anybody out there?' );";
command1.ExecuteNonQuery();
using (var connection2 = new SQLiteConnection(connectionString))
{
connection2.Open();
var command2 = connection2.CreateCommand();
command2.CommandText = "SELECT Text FROM Message;";
var message = command2.ExecuteScalar() as string;
}
}
If I execute this code, it will create in-memory DB named as sharedmemdb and shared cache is enabled while making the connection, so this connection accessible to other connections also. If I run this first time this works pretty fine but if I close the application and run again it throws error "Table Message already exists" and this looks very strange as I created the table in-memory and this should not be available if application restarts.
After getting this error, I looked into the application directory and found the file "sharedmemdb" which means SQLite is not creating the shareable in-memory DB.
Any clue why this is happening?
After moving command to using block:
var connectionString = "Data Source =sharedmemdb; Mode = Memory; Cache = Shared";
using (var connection1 = new SQLiteConnection(connectionString))
{
connection1.Open();
using (var command1 = connection1.CreateCommand())
{
command1.CommandText =
"CREATE TABLE Message ( Text TEXT );" +
"INSERT INTO Message ( Text ) VALUES ( 'Is there anybody out there?' );";
command1.ExecuteNonQuery();
}
using (var connection2 = new SQLiteConnection(connectionString))
{
connection2.Open();
using (var command2 = connection2.CreateCommand())
{
command2.CommandText = "SELECT Text FROM Message;";
var message = command2.ExecuteScalar() as string;
}
}
}
System.Data.SQLite doesn't support the "Mode" parameter (that's Microsoft.Data.Sqlite).
However, in System.Data.SQLite you can use the "FullUri" parameter to pass arguments directly to SQLite, so you can achieve what you wanted by changing your connection string to
FullUri=file:mem.db?mode=memory&cache=shared
Protocol^ ^ ^ ^
DB Name -----| | |
Use memory mode ----+ |
Use shared cache ---------------+
(The first line being the actual connection string, the next couple of lines breaking it down)
I'm using a SQL Server database and C# form, I want to create a graph in C# form with database data.
I use msdn sample codes but it didn't work; no error and no response!
Thank you for helping me ;)
// The Access database
string fileNameString = "data\\chartdata.mdb";
// Initialize a connection string
string myConnectionString = "Data Source=" + fileNameString;
// Define the database query
string mySelectQuery="SELECT Name, Sales FROM REPS ;";
// Create a database connection object using the connection string
SqlConnection myConnection = new SqlConnection(myConnectionString);
// Create a database command on the connection using query
SqlCommand myCommand = new sqlCommand(mySelectQuery, myConnection);
// Open the connection
myCommand.Connection.Open();
// Create a database reader
SqlDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
chart1.Series["Default"].Points.DataBindXY(myReader, "Name", myReader, "Sales");
// Close the reader and the connection
myReader.Close();
myConnection.Close();
you can install and Use reporting services to create graph report and dashboard.
MSDN link for SSRS
I have scanner application on Windows Mobile 6.5 device.
The application keeps crashing after I scan 100 items or so (where I open SqlCe Connection and execute SQL query to populate temporary DataTable with query result).
Here how my C# code looks like:
// Search with SQL
modFunctions.tempItemTable = new AppScanDataSet.itemDataTable();
string connectionString = #"Data Source='" + modFunctions.AppPath() + "AppScan.sdf'; Max Database Size = 512; Max Buffer Size = 4096;";
string strSql = "SELECT * FROM item WHERE Barcode = '" + modFunctions.strBarcode + "'";
using (SqlCeConnection mConnection = new SqlCeConnection(connectionString))
{
mConnection.Open();
//SqlCeConnection mConnection = new SqlCeConnection(connectionString);
SqlCeCommand mCommand = new SqlCeCommand(strSql, mConnection);
// Read all rows from the table into a dataset (note, the adapter automatically opens connection)
SqlCeDataAdapter adapter = new SqlCeDataAdapter(mCommand);
adapter.Fill(modFunctions.tempItemTable);
mConnection.Close();
mConnection.Dispose();
}
Error on crash is:
AppScan.exe
SqlCeException
Not enough storage is available to complete this operation
What can be the problem? I am clearing out tempItemTable (with Dispose() and Clear()). I also added mConnection.Close() and mConnection.Dispose()... but it didn't help.
Also, when I go to Settings > System > Memory.. when application crashed, it seems like I have enough memory available (30MB out of 100MB).
Do I need to dispose adapter? or mCommand?
You are running out of memory. Using DataSet with Windows Mobile is not recommnded, use array or list instead.
I'm trying to save Excel files into the database, I do not want to use filestream as it is required to have a server for that.
So how do I insert/update/select into the table that has a column of type varbinary(max)?
If you want to do it in straight ADO.NET, and your Excel files aren't too big so that they can fit into memory at once, you could use these two methods:
// store Excel sheet (or any file for that matter) into a SQL Server table
public void StoreExcelToDatabase(string excelFileName)
{
// if file doesn't exist --> terminate (you might want to show a message box or something)
if (!File.Exists(excelFileName))
{
return;
}
// get all the bytes of the file into memory
byte[] excelContents = File.ReadAllBytes(excelFileName);
// define SQL statement to use
string insertStmt = "INSERT INTO dbo.YourTable(FileName, BinaryContent) VALUES(#FileName, #BinaryContent)";
// set up connection and command to do INSERT
using (SqlConnection connection = new SqlConnection("your-connection-string-here"))
using (SqlCommand cmdInsert = new SqlCommand(insertStmt, connection))
{
cmdInsert.Parameters.Add("#FileName", SqlDbType.VarChar, 500).Value = excelFileName;
cmdInsert.Parameters.Add("#BinaryContent", SqlDbType.VarBinary, int.MaxValue).Value = excelContents;
// open connection, execute SQL statement, close connection again
connection.Open();
cmdInsert.ExecuteNonQuery();
connection.Close();
}
}
To retrieve the Excel sheet back and store it in a file, use this method:
public void RetrieveExcelFromDatabase(int ID, string excelFileName)
{
byte[] excelContents;
string selectStmt = "SELECT BinaryContent FROM dbo.YourTableHere WHERE ID = #ID";
using (SqlConnection connection = new SqlConnection("your-connection-string-here"))
using (SqlCommand cmdSelect = new SqlCommand(selectStmt, connection))
{
cmdSelect.Parameters.Add("#ID", SqlDbType.Int).Value = ID;
connection.Open();
excelContents = (byte[])cmdSelect.ExecuteScalar();
connection.Close();
}
File.WriteAllBytes(excelFileName, excelContents);
}
Of course, you can adapt this to your needs - you could do lots of other things, too - depending on what you really want to do (not very clear from your question).
It depends on the data access technology you are using. For example, if you use Entity Framework, you can just save a byte array into the database using objects.