Running SQL script as part of visual studio 2010 Setup Project - c#

Good day,
My goal is to create a msi for a windows service and during installation various sql scripts must run.
What I want to do is create a msi that, when the user runs it, it installs the service on the pc and runs 3 .sql scripts, one for creating the database, one for population, and one to add a stored procedure.
I am able to add create a setup project for the service using the msdn overview
My problem is that I have no idea how to run a sql script during the install (and how to specify the sql connection)
Is there any way to do this in visual studio, or will I need to resort to batch files/purchasing InstallShield?
Any help is appreciated,
Regards
Jeff
EDIT: I am using visual studio 2010 Professional and SQLServer 2012

You can run the SQL script during the installation exactly the same way you'd do it in any other C# application.
In the MSDN overview you've mentioned in the question, there is reference to writing your own code during the installation, so I'll assume you already know how to do that.
There are many ways to do this. Here's just one example out of many, quoted from here:
string queryString = "SELECT tPatCulIntPatIDPk, tPatSFirstname, tPatSName, tPatDBirthday FROM [dbo].[TPatientRaw] WHERE tPatSName = #tPatSName";
string connectionString = "Server=.\PDATA_SQLEXPRESS;Database=;UserId=sa;Password=2BeChanged!;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#tPatSName", "Your-Parm-Value");
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader["tPatCulIntPatIDPk"], reader["tPatSFirstname"]));// etc
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}

Related

Cannot find local database on WPF project in Visual Studio

I am trying to create a WPF application for a client and a SQL server is required. I am currently using Visual Studio to develop everything, but I have never used SQL servers outside of web application before. I add a new SQL database to my WPF project by adding a "Service-based Database", and everything works fine. Until I transfer the project over to a different computer where it crashes and gives me the error "System.Data.SqlClient.SqlException: Database not found". Is there something that I'm missing about setting up a database inside my VS project? Why does it only work on my development PC and not any other that I transfer it to?
The code that it crashes on:
string cn_string = Properties.Settings.Default.connection_String;
//Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\_data\db_local.mdf;Integrated Security=True
string cmdString = "SELECT * FROM tbl_Clients";
using (SqlConnection con = new SqlConnection(cn_string))
{
SqlCommand cmd = new SqlCommand(cmdString, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("tbl_Clients");
sda.Fill(dt);
MyDataGrid.ItemsSource = dt.DefaultView;
}
Sorry for my easy questions, I am currently learning programming in high-school. Thanks for all your help.
Using a service-based database requires you to set up a SQL Server service on the machine where you intend to run the WPF client application.
If you want an embedded database that you can xcopy deploy with your application, you should take a look at SQLite. It is, unlike the service-based database that you create in Visual Studio, completely self-contained and doesn't require you to install any service.

Getting Transact SQL query result in C# Application

I'm trying to write a C# application that restores many databases from .bak files placed in a certain folder. To do so I need the databases logical name from the files.
So I want to execute the following query :
RESTORE FILELISTONLY FROM DISK = N'C:\Folder\File'
The problem is: I can't get the result of this to my application, when I execute it in SQL Server Management Studio, it shows the name I want.
I tried to use ExecuteReader function from SqlDataReader but it doesn't return any data.
Can someone help me figure out how to get the result of queries like restore database, backup database into a variable in a C# application ?
Thanks in advance
The command RESTORE FILELISTONLY does return a result set as per the documentation RESTORE Statement - FILELISTONLY. What I did find during testing my code, you need to make sure the user that is running the application has permissions to read the specified file and directory. Otherwise you will run into issues.
For a code example of this:
var command = #"RESTORE FILELISTONLY FROM DISK = N'F:\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\Scratch.bak'";
using (var sqlConnection = new SqlConnection("Server=localhost;Database=Scratch;Trusted_Connection=True;"))
using (var sqlCommand = new SqlCommand(command, sqlConnection))
{
sqlConnection.Open();
var sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
Console.WriteLine($"Logical Name: {sqlDataReader["LogicalName"]}");
Console.WriteLine($"Physical Name: {sqlDataReader["PhysicalName"]}");
Console.WriteLine($"Type: {sqlDataReader["Type"]}");
}
}
You may also find that when trying to work SQL Server management, using the SqlConnection and SqlCommand objects may be more frustrating then they are worth. I strong recommend using the SQL Server Management Objects (SMO). This is actually what management studio uses when you are work with SQL Server. I have an example on GitHub if you are interested in it. Checkout GitHub: SMO Demo.

C# cannot insert data into SQL Server database

I'm recently new at C# and follow a tutorial on connection to the database, the connection for viewing or SELECT command was ok, I made some revision based on the threads of forums to make my code better, but when I was in INSERT for my SQL Server, I have some problems. I was able to insert the data but when I re-run the program the data that I just inserted earlier was not in the database.
Here is my code on insert
string commandText = "INSERT INTO loginInfo (name, pass, role) VALUES(#name, #pass, #role)";
using (connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#name", textBox1.Text);
command.Parameters.AddWithValue("#pass", textBox2.Text);
command.Parameters.AddWithValue("#role", textBox3.Text);
try
{
command.Connection.Open();
command.ExecuteNonQuery();
}
catch
{
}
finally
{
command.Connection.Close();
}
}
I'm trying to create a simple CRUD but not save the data... please help
If you're using the AttachDbFileName= clause in your connection string, you might have fallen victim to a well-known issue : you might just be looking at the wrong database (file) when checking your data.
When running your app in Visual Studio, it will be copying around the .mdf file (from your App_Data directory to the output directory - typically .\bin\debug - where you app runs) and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the connection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The long-term viable solution in my opinion would be to:
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. YourDatabase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=YourDatabase;Integrated Security=True
and everything else is exactly the same as before...
Also see Aaron Bertrand's excellent blog post Bad habits to kick: using AttachDbFileName for more background info.

C# Sql LocalDB Application Slow Performance

I am completely new sql/database applications and am trying out a simple contact management applicaton using Visual Studio 2015 C#. I am using 'SQL Express LocalDB'. I have read on google that it is meant for development purpose, but microsoft also mentions that it could be used for production purpose too.
My problem is that when I try out the application from my developement system, the application first time takes few seconds to load but after that every query runs quickly. When I tried this on one my friends system, it takes time everytime I try to use any query. The database is just with 20-30 records.
I create new connection using 'new SqlConnection' and then execute command created by 'new SqlCommand' and after executing query I close the connection.
Here is the code snippet from my app
SqlConnection sqlConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\ContactsDB.mdf""; Integrated Security = True; Connect Timeout = 30";);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = sqlConnection;
sqlCmd.CommandText = "SELECT Id, first_name, last_name from ContactsMaster ORDER BY first_name";
sqlConnection.Open();
SqlDataReader reader = sqlCmd.ExecuteReader();
try
{
while (reader.Read())
{
ListViewItem lvi = new ListViewItem(reader["first_name"]);
listViewItems.Add(lvi);
lvi.SubItems.Add(reader[0].ToString());
}
}
finally
{
reader.Close();
}
sqlConnection.Close();
Q. Should I keep the connection open all the time while app is running? I don't think this should be suggested. As if app crashes database can get corrupt.
One of the backdrop which ppl saying that LocalDB closes the connection every new milliseconds. So should I keep pinging the database every few milliseconds? Or I should not use localdb in production at all?
I want to make the app such that the requirement goes really low regaridng the database prerequisites. Like LocalDB installation is really seamless.
I have not used SQL Server Express, does Express installation is also seamless like LocalDB and can I use the connection string like LocalDB in Express too, giving the .mdf filename directly?
localdb has auto shutdown. default is 5 min. you can set it to higher value (ie: 12hour).
max is 65535 min.
see: How to prevent SQL Server LocalDB auto shutdown?
also sqlexpress autoshutdown is 1hour if im not wrong.
symptoms on my pc:
first open is 10- 30 seconds slow. if i reopen app right after it is below 1 second. if i wait for a while it is slow again
There are many things to take in count for ddbb performance, it's not a simple question. For such small amount of records there shouldn't be performance problems. Try storing the ddbb files in another disk different from OS disk, and even better, place data file and log file in different disks too.
About your question, connections must be always closed and disposed properly in a finally block or inside a using block.
Sql Express is very easy to install, and also use a connection string, been the biggest difference that it can be used across the network.
Finally moved to SQLite and that is much faster in compare to SQLLocalDB.

Server cannot connect to SQL server

I have a C# Service project where I am connectiong to SQL and retrieving data.
When I debug locally eg: in the Visual Studion Developement Server it works nice.
But when I upload to the server(simply localhost/MyProject/) The SqlCommand() is throws an exception. Are there way to get more information on SqlCommand()?
What permissions I should set to run web service on the server?
Maybe mode details:
The project within VS2008 envirenoment is works nice:
http://localhost:50301/GetJpeg.aspx?ra=224.5941&dec=-1.09&width=1000&height=1000&scale=1
but on the http://localhost/GetJpeg.aspx?ra=224.5941&dec=-1.09&width=1000&height=1000&scale=1 no.
The exception is not really exception the:
SqlDataReader reader does not return any result in second case:
reader = cmdCenter.ExecuteReader();
if (reader.Read())
{
//Do Something
reader.Close();
}
else
{
throw new Exception("Request is failed");
}
Thanks Arman.
EDIT
Just for information:
In one case the code is debugged via ASP.NET Developement Server and the second one is running on IIS 7.0
UPDATE
After deep digging I discovered: The connection is open and connected, usual queries is ok, but queries with stored functions are failing... can be that IIS miss configuration ?
If you are using the SqlCommand control (drag-dropped onto a page) instead of the SqlCommand object (code), your best bet will be to add a page-level error handler (http://msdn.microsoft.com/en-us/library/ed577840.aspx).
Most likely, the problem is that your connection string uses SSPI for authenticating to the SQL Server (integrated/domain security). That would allow you to connect via Visual Studio, but not once it is deployed. You might want to look at this article (http://msdn.microsoft.com/en-us/library/bsz5788z.aspx). The answers in that article are not ideal, but they will get you moving along. The better approaches can get pretty complicated. Read-up on those once you get your app working again.
You can attach the Debugger in VS to IIS on your box and continue debugging. To do this, go to Debug->Attach to Process and then find the W3wp.exe process that is running the Application Pool your application is running in.
try
{
using (SqlConnection connection = new SqlConnection("Your connection string here"))
{
using (SqlCommand command = new SqlCommand("your sql here", connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
}
}
}
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception);
}
Breakpoint in the catch to see the exception in your debugger.

Categories

Resources