Ignore "missing" database while executing SQL - c#

I'm writing an application that creates a SQL Server database for another program. For this I load a large SQL-script containing the CREATE DATABASE, CREATE TABLE and so on.
The first lines of the script is:
/*CREATE DATABASE*/
USE [master]
GO
CREATE DATABASE [MultiRisk5] COLLATE Latin1_General_CI_AS
GO
USE [MultiRisk5]
GO
And the C# code:
var sqlConn = new SqlConnection("myConnection");
var cmd = new SqlCommand("mySqlScript", sqlConn);
sqlConn.Open();
cmd.ExecuteNonQuery();
sqlConn.Close();
When I run the program I get an exception on the USE statement that tells me that the database MultiRisk5 doesn't exist.
How can this be, when I just created the database? The script runs fine when executed in SQL Server Management Studio.

You can't load a script in c# that has GO in it and run it.
GO is recognised the SQL Server client tools only, and as a batch separator. The database engine won't recognise it. See these questions for more on how to do this
Execute sql file on SQL Server using C#
Add column to table and then update it inside transaction
Also, does the SqlConnection try to connect to MultiRisk5? if so, this will error too before USE master is run

You may want to try executing your query in a try catch block to see what comes back. That would be a good first step into figuring out the issue.

Maybe your app does not have the appropriate rights to create the database ?
You should check whether the database creation succeeds before going on.

Related

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.

Create database, tables and stored procedure using existing script from txt file using C#

I have developed a winform application using C# and SQL Server 2008. Now my job is to implement it on client's machine.
I am looking for the best way to create the database tables and stored procedure on client machine to run this application. I have generated the script of all my database objects. And now i want to create all database objects on client's machine with one click C# code that read each table or stored procedure script file (i.e. .sql or .txt) and create them.
No need for smo, but a bit ugly
SqlCommand getDataPath = new SqlCommand("select physical_name from sys.database_files;", baseConnection); // get default path where the sqlserver saves files
string temp = getDataPath.ExecuteScalar().ToString();
temp = temp.Replace(temp.Split('\\').Last(), string.Empty);
StringBuilder sqlScript = new StringBuilder(Scripts.CreateDatabase); //CreateDatabase could be in ressources
///The #### are used to replace the hardcorededpath in your script
sqlScript.Replace("####MAINDATAFILENAME####", string.Concat(temp, "test.mdf"));
sqlScript.Replace("####LOGDATAFILENAME####", string.Concat(temp, "test_log.ldf"));
string[] splittedScript = new string[] { "\r\nGO\r\n" }; //remove GO
string[] commands = sqlScript.ToString().Split(splittedScript,
StringSplitOptions.RemoveEmptyEntries);
Then run every command in commands(SqlCommand cmd = new SqlCommand(command[x], baseConnection);)
Note: For some reasons this needs adminrights, so create a manifestfile.
You need to use SMO to complete this task. The normal ADO.NET stuff will complain about multi-statement execution and the like. It's really pretty easy once you integrated with SMO and have the scripts.
Visual Studio supports database projects, which generates deployment scripts for you. It also allows for deployments from scratch or to upgrade existing databases. The deployments can be automated as part a build within visual studio or the build server. If you're using TFS you can also source-control your database.
Basically no more messing about with scripts!
http://msdn.microsoft.com/en-us/library/ff678491(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/xee70aty.aspx

How to enter this SQL code into .NET

I have a bulk insert that works fine in SQL.
I can't figure out how to get the SQL code to work in C#.
CMD.CommandText = "???"
I've tried so many ideas and keep getting an error. The bulk insert is below:
Use Lab2
GO
BULK
INSERT [dbo].[tmpPerson]
FROM 'C:\Temp\Input2.txt'
WITH (
ROWTERMINATOR ='\n');
How about having a look at SqlBulkCopy Class
Lets you efficiently bulk load a SQL Server table with data from
another source.
Microsoft SQL Server includes a popular command-prompt utility named
bcp for moving data from one table to another, whether on a single
server or between servers. The SqlBulkCopy class lets you write
managed code solutions that provide similar functionality. There are
other ways to load data into a SQL Server table (INSERT statements,
for example), but SqlBulkCopy offers a significant performance
advantage over them.
I used the Server object in the Microsoft.SqlServer.management namespace to do this same kind of thing. It allows you to have the GO word in commands, where using the SqlCommand it expects that each instance of SqlCommand represents a single command.
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
SqlConnection conn = new SqlConnection(sqlConnectionString);
Server server = new Server(new ServerConnection(conn));
server.ConnectionContext.ExecuteNonQuery(script);

Backup C# Windows application data

I'm designing a Windows application using C# in Visual Studio. I need to create back up button or something that would back up my data. How do I do that?
Simlpy create a back up for you data base. I should not be a big problem to triger that proces from your code.
check this sites:
How to Create Full Database Backup on MS SQL Server for a Database using T-SQL Backup Database command and SqlCmd Utility
How to: Create a Full Database Backup
Create a new store procedure similar to the content below and call it from your code.
Copy Code USE AdventureWorks2008R2;
GO
BACKUP DATABASE AdventureWorks2008R2
TO DISK = 'Z:\SQLServerBackups\AdventureWorks2008R2.Bak'
WITH FORMAT,
MEDIANAME = 'Z_SQLServerBackups',
NAME = 'Full Backup of AdventureWorks2008R2';
GO

Made this query in SQL Server Management Studio Express how to use it?

For my database I create a new query and wrote
select * from dbname
using SQL Server Management Studio Express 2005. Saved it by name SQLQuery1.sql on the desktop.
Now I would like to call this query from C# code when an ASP.NET button is clicked and display the results in a gridview.
How do I call the query? Can I tell Visual Studio 2008 to please execute the query stored in 'sqlquery1.sql' ?
Where do I store the results so that I can bind them the display controls like a gridview, or traverse the data?
This is a website in C#, ASP.NET, Visual Studio 2008, and database is on the same computer using SQL Server 2005 Express
You cannot just execute a SQL script you stored on your computer's desktop from an ASP.NET website.
You can either:
turn your query into a stored procedure in SQL Server, something like:
CREATE PROCEDURE dbo.proc_MyQuery
AS
SELECT (list of columns)
FROM dbo.MyTable
WHERE (condition)
When you do this, you can create a SqlCommand in your C# code and call that stored procedure and retrieve the results back.
or:
you can execute the query directly from your C# code by creating a SqlConnection and a SqlCommand object and running that SQL statement.
These are both absolutely basic ADO.NET features - you should find tons of learning resources online for this.
For instance:
ADO.NET 101 - Data Access with ADO.NET
ADO.NET 101: SQL Connection
ADO.NET 101: SqlCommand / Your guide to using this ADO.NET object to execute SQL Server commands
Using ADO.NET for beginners
ADO.NET for Beginners - Part 1
Which ever way you go, you basically need to have a SqlConnection to your database, and then a SqlCommand to execute the query. If you want to store the data so you can both bind it to a Gridview as well as navigate it in code, you probably want to store it in a DataTable. So your code would look something like this:
DataTable resultTable = new DataTable();
using(SqlConnection con = new SqlConnection("your connection string here"))
{
string sqlStmt = "SELECT (columns) FROM dbo.YourTable WHERE (condition)";
using(SqlCommand cmd = new SqlCommand(sqlStmt, con))
{
SqlDataAdapter dap = new SqlDataAdapter(cmd);
dap.Fill(resultTable);
}
}
and then to bind to the gridview, you'd use something like:
myGridView.DataSource = resultTable;
myGridView.DataBind();
and to navigate the DataTable, you can step through its .Rows() collection of data rows.
In your server side event handler you will need to open the file from the desktop, read in the SQL, and then use the SQL to databind the grid.
This would depend on the identity that the website code runs under having read access to the desktop. By default it won't so you would need to give that identity (NETWORK_SERVICE?) permission. This could open up horrible security holes.
You would be better off moving the SQL somewhere more accessible, like web.config, or a file in the website directory.

Categories

Resources