System.Data.sqlClient will only create default database on server - c#

Background:
I am using sql statements to create a Temp database on a server which will store data until it is needed further by my client program.
Problem:
My sql statement to create the database works properly and creates the database with all the required specifications when run through Sql Management studio, on the other hand when my program executes the statement it only creates a database with the 'Default' settings except for the name.
Questions:
Why is this?
How can I make it create a database with my specifications
Sql statement:
CREATE DATABASE Temp ON PRIMARY(
NAME = Temp
, FILENAME = 'C:\Temp.mdf'
, SIZE = 2MB
, FILEGROWTH = 10%) LOG ON (
NAME = Temp_Log
, FILENAME = 'C:\Temp.ldf'
, SIZE = 1MB, MAXSIZE = 70MB
, FILEGROWTH = 10%)
Code:
public void AcuConvert()
{
using (DestD)
{
SqlCommand command = new SqlCommand();
DestD.Open();
command.Connection = DestD;
foreach (var item in Entity.SqlDestinationQueries.ToList())
{
command.CommandText = item.Query;
command.ExecuteNonQuery(); //This is where the command is run
}
foreach (var item in Entity.SystemQueries.ToList())
{
command.CommandText = item.Query.Replace("#Sys", SysD.Database);
command.ExecuteNonQuery();
}
foreach (var item in Entity.InsertQueries.ToList())
{
command.CommandText = item.Query.Replace("#Source", SourceD.Database); ;
command.ExecuteNonQuery();
}
}
}

Have you tried using SQL Server Management Objects instead of a raw SQL statement?
For example:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
...
// Connect to the default instance
Server server = new Server();
// Establish new database details
Database database = new Database(server, "MyTempDB");
// Add primary filegroup details
database.FileGroups.Add(new FileGroup(database, "PRIMARY"));
// Set Primary datafile properties
DataFile primaryFile = new DataFile(database.FileGroups["PRIMARY"],
"MyTempDB_Data", "C:\\MyTempDB.mdf");
primaryFile.Size = 2048; // Sizes are in KB
primaryFile.GrowthType = FileGrowthType.Percent;
primaryFile.Growth = 10;
// Add to the Primary filegroup
database.FileGroups["PRIMARY"].Files.Add(primaryFile);
// Define the log file
LogFile logfile = new LogFile(database, "MyTempDB_Log", "C:\\MyTempDB_Log.ldf");
logfile.Size = 1024;
logfile.GrowthType = FileGrowthType.Percent;
logfile.Growth = 10;
logfile.MaxSize = 70 * 1024;
// Add to the database
database.LogFiles.Add(logfile);
// Create
database.Create();
database.Refresh();
You can connect to the server with specific credentials, too, of course:
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.server.aspx
If, however, you're stuck with using text scripts to create your database, I'd ensure that your Initial Catalog is set correctly (i.e. to 'master') in your connection string and your user has the necessary permissions - CREATE DATABASE / CREATE ANY DATABASE / ALTER DATABASE. If this still doesn't give you any joy, try stripping out the rest of your C# code and run the create SQL independently of the other statements - it could be that there's a side-effect from a preceding query. Use Profiler to see exactly what's running as you add them back in.
Edit:
I tested your script against a local SQL Server instance (2012 SqlLocalDB) via a small C# program using SqlClient and it ran just fine after changing the file paths to ones I had write access to (root of C is protected by default). The only other amendment was that the Primary size had to start at 3MB or more. Any smaller and the default tables could not be created. This may be another avenue of investigation for you to explore.

Your alternative option could be to use the Process class to run the sqlcmd.exe
Eg.
var process = Process.Start(WORKING_PATH, argument);
%WORKING_PATH% being "C:\tools\sql\sqlcmd.exe"
%argument% being "C:\scripts\Create.sql"
I use this strategy to dump test data into test environments when bootstrapping acceptance test fixtures.
Cheers

Related

I try to write something in a oracle database with c# (winforms) and I can only get the SELECT Statement to work, not the INSERT Statement

I wrote the following code for connecting to an oracle database with my c# code:
private string GenerateConnectionString()
{
return "Data Source=( DESCRIPTION = ( ADDRESS_LIST = ( ADDRESS = ( PROTOCOL = TCP )( HOST = 192.168.X.XXX)( PORT = 1521 ) ) )( CONNECT_DATA = ( SERVER = DEDICATED )( SERVICE_NAME = XXXX ) ) ); User Id= xxxxxx; Password = xxxxxx;";
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
using (OracleConnection connection = new OracleConnection(GenerateConnectionString()))
{
connection.Open();
lblState.Text = connection.State.ToString();
OracleCommand oc = connection.CreateCommand();
oc.CommandText = "INSERT INTO TABLE (NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, NO10, NO11, NO12, DATE) VALUES(1,2,3,1,1,1,'{txb_Textbox1.Text}',5,0.5,10,11,12,TO_DATE('09.07.2020 16:24:00', 'DD.MM.YYYY HH24:MI:SS'))";
oc.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show( "Exception: " + ex.Message );
lblState.Text = ex.Message;
}
}
I also installed all the necessary drivers for connecting to the oracle database and added the System.Data.OracleClient.dll as a reference to my c# project and added the "oraocci19.dll" and "oraocci19d.dll" file to the project file. I also added the oracle client to the system environment variables under PATH. Furthermore, I declared using System.Data.OracleClient;at the beginning of my overall code.
Please don't tell me that I do not use the latest Oracle Data Access Components (ODACs). I know that. We have a very old Oracle Database and I like the idea that I only need to install a few oracle dll's for it to work.
I just don't know what to do and spent the whole Friday and the whole weekend researching so that I could write to the Oracle database. I hope that someone experienced recognizes the problem directly and can help me.
Thank you very much in advance! :) Best regards
Edit1: Maybe I should try the other Oracle Data Access Components (ODACs) and their dlls. But normally my dll files should also work. A colleague of mine used my ODAC Installation and he said everything worked with it. But, he only had to read data from an Oracle table and not write in one.
Edit2: I got the problem! I was able to find the solution. Their was a mistake in my Oracle Prompt in the string. The C# code was correct. Here on stackoverflow I have of course reformulated and generalized the Oracle prompt string because it contains trusted data. The error was in the Oracle Command. This thread can be closed. Pete -S- got the right answer!
You could try this:
//Do the insert
oc.CommandText = "INSERT INTO TABLE (NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, NO10, NO11, NO12, DATE) VALUES(1,2,3,1,1,1,'{txb_Textbox1}',5,0.5,10,11,12,TO_DATE('09.07.2020 16:24:00', 'DD.MM.YYYY HH24:MI:SS'))";
oc.ExecuteNonQuery;
//Retrieve in a separate action (you have to update your command to SELECT from INSERT)
oc.CommandText = "SELECT * FROM TABLE"; Statement
OracleDataReader reader = oc.ExecuteReader();
Another thing you can look at, is the CommandBuilder; but, it's the easy way out then a good solution. You can then specify the SELECT and the command builder will create the INSERT, UPDATE and DELETE commands.
Other thoughts
I don't think you can bind a data reader to a .DataSource. You can load a data table from a data reader, see this example.
Here is more information on DataAdapters and DataReaders
To UPDATE/INSERT: use .ExecuteNonQuery
To SELECT: there are different options, one is to build a DataTable via DataAdapaters and bind the data source using the data table.
You are doing it in the wrong order, you need to set the command text first and then execute the command (with ExecuteNonQuery() or ExecuteReader()):
OracleCommand oc = connection.CreateCommand();
oc.CommandText = "INSERT INTO TABLE (NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, NO10, NO11, NO12, DATE) VALUES(1,2,3,1,1,1,'{txb_Textbox1}',5,0.5,10,11,12,TO_DATE('09.07.2020 16:24:00', 'DD.MM.YYYY HH24:MI:SS'))";
OracleDataReader reader = oc.ExecuteReader();

Sql server SMO partial backup

I have a database in SQL Server 2008 R2, that uses the Simple recovery model.
The database contains a filegroup, where the bulk of the data resides (>20GB of images). These images are not critical for the application.
I want to backup the database from C# using Sql Server SMO. But I only want to backup the database structure (the PRIMARY filegroup; everything except the non-essential images). I want to do this in order to keep the backup size small.
In my C# code, I am setting the backup action to BackupActionType.Files, and I am only including the PRIMARY filegroup inside the DatabaseFileGroups collection, so it should only backup the database structure, and not the images.
But when I run the backup, I get this exception:
System.Data.SqlClient.SqlError: The primary filegroup cannot be backed up as a file backup because the database is using the SIMPLE recovery model. Consider taking a partial backup by specifying READ_WRITE_FILEGROUPS.
My question is, how can I specify READ_WRITE_FILEGROUPS from inside C# code, using Sql Server SMO? The exception shows me how to do so in T-SQL, but I want to do the same thing in C#.
Here is the code I am using:
class Program
{
static string DbName = PATH_TO_DATABASE;
static string connString = CONNECTION_STRING;
static void Main(string[] args)
{
ServerConnection serverConn = new ServerConnection();
serverConn.ConnectionString = connString;
Server server = new Server(serverConn);
Backup backup = new Backup() { Database = DbName };
backup.Action = BackupActionType.Files;
backup.DatabaseFileGroups.Add("PRIMARY");
backup.Devices.AddDevice("D:\\backup.bak", DeviceType.File);
backup.Initialize = true;
backup.ContinueAfterError = false;
backup.Incremental = false;
backup.Complete += (snd, e) => { Console.WriteLine("Complete"); };
backup.PercentComplete += (snd, e) => { Console.WriteLine("Percent " + e.Percent); };
backup.SqlBackup(server);
serverConn.Disconnect();
}
}
solution is very simple.
Just in SQLSERVER rigth-click on database and in Properties Window in Option tab change Recovery Mode To Bulk-logged
secound Solution by T-SQL:
USE [master]
GO
ALTER DATABASE [databasename] SET RECOVERY BULK_LOGGED WITH NO_WAIT
GO

SQL Server CE: Suppress modifications of database file?

we have an application that has a local SQL Server CE database file. When we open the database, but don't do any changes to it, the database file is changed anyway:
using (var connection = new SqlCeConnection("Data Source='data.sdf';File Mode='Shared Read';Encrypt=FALSE;LCID=1033"))
{
connection.Open();
using (var context = new DataContext(connection))
{
}
}
This changes some bytes at the very beginning of the sdf-file.
Is there any way to prevent this?
Yes, you can enable read only mode in the connection string. Also you may need to specify a temp path in this case:
string connectionString = ...;Mode = Read Only;Temp Path= ...;
More info.

Visual studio mdf database structure modified then lost after publish

Service-based database is new to me. I would like to create a simple database application with:
Service-based database -> Dataset (mdf)
LINQ to SQL (L2S) Classes
This application will be installed on a lot of individual machines every instances has it's own mdf database.
Installation is done by Clickonce.
My problem is:
I publish my application and install it on user machines
Users put some data into the database
Turns out that we need another table or column
Publish the application again with the extended database and install on user machines
User starts with a new database and original data lost!
(If I am not modifying the database structure than all data is in the database after next Clickone update)
Questions:
If I made only alter table- or add table- like modifications is there any way to preserve data during the next Clickonce update?
Thank you in advance!
Dave
I have found a solution.
If you modify your database model in visual studio Clickonce will automatically recreate all tables after installation (newly published application with modified tables).
Clickonce save the old database to a specified location:
if (ApplicationDeployment.IsNetworkDeployed && ApplicationDeployment.CurrentDeployment.DataDirectory != null)
string preDatabase = Path.GetFullPath(Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory,#".pre\sampledatabase.mdf"));
This .pre directory is created by Clickonce. You always check if this file is exist or not. If it is exist you have to copy data from old tables to new tables OR you will loose all data from old tables!
How to copy data from one database to another very similar database? My answer is the following: copy all table to another table with SqlBulkCopy.
// Create source connection
using (
var source =
new SqlConnection(
String.Format(
#"Data Source=(LocalDB)\v11.0;AttachDbFilename={0};Integrated Security=True;",
preDatabase)))
{
source.Open();
// Create destination connection
using (var destination = new SqlConnection(Settings.Default.mdcdbConnectionString))
{
destination.Open();
DataTable dt = source.GetSchema("Tables");
foreach (string tablename in from DataRow row in dt.Rows select (string) row[2])
{
App.Logger.LogText(String.Format("Copying table {0}", tablename));
using (var cmd = new SqlCommand(String.Format("TRUNCATE TABLE {0}", tablename), destination))
{
cmd.ExecuteNonQuery();
//App.Logger.LogText(String.Format("truncate table {0}", tablename));
}
using (var cmd = new SqlCommand(String.Format("SELECT * FROM {0}", tablename), source))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
var bulkData = new SqlBulkCopy(destination)
{
DestinationTableName = tablename
};
// Set destination table name
bulkData.WriteToServer(reader);
// Close objects
bulkData.Close();
//App.Logger.LogText(String.Format("Copy success {0}", tablename));
}
}
}
destination.Close();
}
source.Close();
}
Wish you good coding!
Dave

Create database without wizard c#

Today i'm working on a project where I will create a relational database through source code and not through the built-in wizard.I have been looking for tutorials which explain to me the processes of doing this but seem to not be able to do so. Most have tutorials on how to use the build-in wizard and add content to tables, my main goal is to actually have a utility that users could use which includes a self-building database. if you have examples of this, I would greatly appreciate it or if you know of any good tutorials that will be helpful too
Thanks!
class Program
{
static string strcon = #"user id = sde ; password = passrd;
server =dfgserver;database =valrollclients";
static SqlCommand cmdinserted = new SqlCommand();
static SqlConnection con; //declaring a connection object
static void Main(string[] args)
{
cmdinserted.CommandText = "[dbo].[prcinsert_client]";
cmdinserted.CommandTimeout = 0;
cmdinserted.CommandType = CommandType.StoredProcedure;
cmdinserted.Connection = con;
cmdinserted.Parameters.Add("#client_name",
SqlDbType.VarChar, 12).Value = "me";
cmdinserted.Parameters.Add("#client_lastname",
SqlDbType.VarChar, 15).Value = "abutair";
cmdinserted.Parameters.Add("#client_age ",
SqlDbType.Int, 4).Value = 4;
try
{
con.Open(); //open connection
cmdinserted.ExecuteNonQuery(); //execute the stored procedure
con.Close();//close connection
}
catch (SqlException) //catch an error
{
throw; //throw it back to the calling method
}
This is the code you have to run on the server:
USE master;
GO
CREATE DATABASE Sales
ON
( NAME = Sales_dat,
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL \DATA\saledat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = Sales_log,
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\salelog.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB ) ;
GO
You can add it into a SqlCommand. You will need an SqlConnection which I see you have.
Hope it helps.
It seems like this is being made way more complicated than it needs to be if you're planning to use SQL server.
Your application offers the user a way to enter a SQL server instance location and user with admin rights.
You then have a class with various methods which create your database, create your tables etc.
So you would do:
1) If not exists create database X.
2) IF not exists create tables A B C etc
3) alter the tables to setup the relations
4) If not exists create stored proc spA spB etc etc
and just build up the database that way.
Each step above would be a separate method which executes some inline SQL.
If you write the SQL to always check if the thing you're going to create exists it can be used to upgrade as well as create.

Categories