Creating a database programmatically in SQL Server with parameters - c#

As of right now I have a working piece of code, that looks something like this:
string sqlCreateDBQuery = " CREATE DATABASE "
+ "["+databaseName+"]"
+ " ON PRIMARY "
+ " (NAME = Data, "
+ " FILENAME = '" + strDataPath + databaseName + ".mdf', "
+ " FILEGROWTH = 1MB) "
+ " LOG ON (NAME = Log, "
+ " FILENAME = '" + strLogPath + databaseName + "_log.ldf', "
+ " FILEGROWTH = 10%) "
+ " COLLATE Latin1_General_CI_AS ;";
SqlCommand command = new SqlCommand(sqlCreateDBQuery, connection);
This has, with my current understanding, the potential issue of SQL-Injection attacks and well, user input errors.
So my question is, how do I safely create a database programmatically on an SQL Server where the user is able to name the database?
I know that one should use parameterized SQL-Queries to avoid SQL-Injection attempts, but for some reason I can´t seem to figure out how to do this for creating a new database or users/logins.
I´ve also read, that there is the option to use the SQL Server Management Object API as described in this answer here: Creating a database programmatically in SQL Server
Unfortunately this is not an option for us.
As of right now I haven´t figured out how to use a parameterized Query for this task.
This is what I would assume what the Code should look like to achieve this, but with no working result.
SqlCommand command = connection.CreateCommand();
command.CommandText = " CREATE DATABASE "
+ "#dbName"
+ " ON PRIMARY "
+ " (NAME = Data, "
+ " FILENAME = #dataPath, "
+ " FILEGROWTH = 1MB) "
+ " LOG ON (NAME = Log, "
+ " FILENAME = #logPath, "
+ " FILEGROWTH = 10%) "
+ " COLLATE Latin1_General_CI_AS ;";
command.Parameters.AddWithValue("#dbName", StrDBName);
command.Parameters.AddWithValue("#dataPath", $"{strDataPath}{StrDBName}.mdf");
command.Parameters.AddWithValue("#logPath", $"{strLogPath}{StrDBName}_log.ldf");
I´ve also read Here that this should be possible with dynamic SQL, but sadly all my attempts either ended in Syntax errors or the parameters not being replaced by the actual values.
Am I missing something here or is this just not as trivial as I initially thought?

Related

Same SQL Query Working in Management Studio but Not Working From Visual Studio [duplicate]

This question already has answers here:
Incorrect syntax near 'GO'
(9 answers)
Closed 2 years ago.
I have a SQL query which creates a database and declares the path of an mdf and its log files. The same query works when I execute it in management studio (I am sure it's the same query I copy paste it from SQL Profiler) but gives a syntax error below:
incorrect syntax near go.
I have tried using executeNonQuery, ExecuteReader and ExecuteScalar to execute my query but nothing worked. It was giving syntax error due to the lack of newlines in query from my code hence the newline methods in the query. Any help would be appreciated.
Visual Studio code:
string truvamdf = #"C:\Truva\Data\"+VeritabaniAdiTextBox.Text+".mdf";
string truvaldf = #"C:\Truva\Data\"+VeritabaniAdiTextBox.Text+"_log.ldf";
string connectionString = (#"" + File.ReadAllText(#"C:\Truva\Ivdexcel\IVDVeritabaniconfig.ini") + "");
string cmdtext = "" +
"USE[master] " + Environment.NewLine + "" +
"GO " + Environment.NewLine + "" +
"DECLARE #mdfPath NVARCHAR(max), #ldfPath NVARCHAR(max) , #SQL NVARCHAR(MAX), #instName NVARCHAR(max) = '" + VeritabaniAdiTextBox.Text + "' " + Environment.NewLine + "" +
"SELECT #mdfPath = '" + truvamdf + "' " + Environment.NewLine + " " +
",#ldfPath = '" + truvaldf + "' " + Environment.NewLine + " " +
"FROM master.sys.master_files WHERE database_id = 1 " + Environment.NewLine + "" +
"SELECT #SQL = " + Environment.NewLine + "" +
"'CREATE DATABASE ["+VeritabaniAdiTextBox.Text+ "] " + Environment.NewLine + " " +
"CONTAINMENT = NONE " + Environment.NewLine + " " +
"ON PRIMARY " + Environment.NewLine + "" +
"(NAME = N'''+#instName+''', FILENAME = N'''+#mdfPath+''' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) " + Environment.NewLine + " " +
" LOG ON " + Environment.NewLine + " " +
" (NAME = N'''+#instName+'_log'', FILENAME = N'''+#ldfPath+''' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10 %)' "+Environment.NewLine+ " " + Environment.NewLine + "" +
"EXECUTE(#SQL) " + Environment.NewLine + " " + Environment.NewLine + "" +
" GO ";
// try
// {
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand cmd = new SqlCommand(cmdtext, connection);
cmd.ExecuteNonQuery();
}
The same SQL query in SSMS:
USE[master]
GO
DECLARE #mdfPath NVARCHAR(max), #ldfPath NVARCHAR(max) , #SQL NVARCHAR(MAX), #instName NVARCHAR(max) = 'dddssd'
SELECT #mdfPath = 'C:\Truva\Data\dddssd.mdf'
,#ldfPath = 'C:\Truva\Data\dddssd_log.ldf'
FROM master.sys.master_files WHERE database_id = 1
SELECT #SQL =
'CREATE DATABASE [dddssd]
CONTAINMENT = NONE
ON PRIMARY
(NAME = N'''+#instName+''', FILENAME = N'''+#mdfPath+''' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
(NAME = N'''+#instName+'_log'', FILENAME = N'''+#ldfPath+''' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10 %)'
EXECUTE(#SQL)
GO
I just deleted the GO statements from the query and it works now!!

Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints. C# Windows forms

I was working on Firebird Server and SQL Server to update database from the Firebird database to the SQL server database. This update was done using a tool called Updater Tool. I have created this tool using C# Windows Application, it was successfully running.
This database contains financial data. The client has provided a Firebird database backup file with data up to 2016, and it was successfully updating the database.
I have restored the backup file successfully on my system, so I have created a setup file and installed it on the client system and I started updating the database. The client has the latest data, it was working and updating SQL database.
It was updating some tables and then got an error "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints." and operation was cancelled.
What I need is, whenever I get this type of error, I want to skip or ignore the error and the remaining part should update the database. How I have created the update tool means,
I have created arrays that store all table columns. This is done because only selected columns from Firebird database table columns were updated in the SQL Server database.
Each table contains 2 primary key columns with this I have created a comparison of the two databases to find which data is not present in the SQL Server database. The compared table rows are stored in DataTable.
The updating is done by selecting a date. In updater tool, I have provided a datetimepicker, the client can select the date and update his database. What client has done means that the SQL Server database was updated up to 2015 and client wants to update data from 2017 that means client left 2016 data, so in database comparison it gets the entire data above 2017. Here is a link, based on this I have created comparison method Database Comparison.
Below is the code how I update the database
public void UpdateToDatabse(DataTable table, string selectQuery, ArrayList columnNames, string tableName)
{
string fbSelectStatementQuery;
int insertedCount = 0;
int notInsertedCount = 0;
listBox1.Items.Add("Total Rows to update " + table.Rows.Count);
using (FbConnection fbconn = getFbConnection(textBox1.Text))
{
FbCommand fbcmd = new FbCommand();
fbcmd.Connection = fbconn;
for (int i = 0; i < table.Rows.Count; i++)
{
if (tableName == "COMPDATA" || tableName == "COMPMAS")
{
fbSelectStatementQuery = #"" + selectQuery
+ " Where \"" + table.Columns[0].ColumnName + "\"='" + table.Rows[i][0] + "'";
fbcmd.CommandText = fbSelectStatementQuery;
}
else if (tableName == "DLYPRICEBSE" || tableName == "DLYPRICENSE")
{
fbSelectStatementQuery = #"" + selectQuery
+ " Where \"" + table.Columns[0].ColumnName + "\"='" + table.Rows[i][0] + "' and \""
+ table.Columns[1].ColumnName + "\"='" + Convert.ToDateTime(table.Rows[i][1]).ToShortDateString() + "' and \""
+ table.Columns[2].ColumnName + "\"='" + table.Rows[i][2] + "' and \""
+ table.Columns[3].ColumnName + "\"='" + table.Rows[i][3] + "' and \""
+ table.Columns[4].ColumnName + "\"='" + table.Rows[i][4] + "' and \""
+ table.Columns[5].ColumnName + "\"='" + table.Rows[i][5] + "' and \""
+ table.Columns[6].ColumnName + "\"='" + table.Rows[i][6] + "' and \""
+ table.Columns[7].ColumnName + "\"='" + table.Rows[i][7] + "' and \""
+ table.Columns[8].ColumnName + "\"='" + table.Rows[i][8] + "' and \""
+ table.Columns[9].ColumnName + "\"='" + table.Rows[i][9] + "' and \""
+ table.Columns[10].ColumnName + "\"='" + table.Rows[i][10] + "' and \""
+ table.Columns[11].ColumnName + "\"='" + table.Rows[i][11] + "' and \""
+ table.Columns[12].ColumnName + "\"='" + table.Rows[i][12] + "' and \""
+ table.Columns[13].ColumnName + "\"='" + table.Rows[i][13] + "' and \""
+ table.Columns[14].ColumnName + "\"='" + table.Rows[i][14] + "' and \""
+ table.Columns[15].ColumnName + "\"='" + table.Rows[i][15] + "'";
fbcmd.CommandText = fbSelectStatementQuery;
}
else if (tableName == "EQTYHIS")
{
fbSelectStatementQuery = #"" + selectQuery
+ " Where \"" + table.Columns[0].ColumnName + "\"='" + table.Rows[i][0] + "' and \""
+ table.Columns[1].ColumnName + "\"='" + Convert.ToDateTime(table.Rows[i][1]).ToShortDateString() + "' ";
fbcmd.CommandText = fbSelectStatementQuery;
}
else
{
fbSelectStatementQuery = #"" + selectQuery
+ " Where \"" + table.Columns[0].ColumnName + "\"='" + table.Rows[i][0] + "' and \""
+ table.Columns[1].ColumnName + "\"='" + table.Rows[i][1] + "' ";
fbcmd.CommandText = fbSelectStatementQuery;
}
using (FbDataReader fbreader = fbcmd.ExecuteReader())
{
while (fbreader.Read())
{
string colValues = #"( ";
string columns = #"";
int j = 0;
while (j < columnNames.Count)
{
if (j < columnNames.Count - 1)
{
columns += "\"" + columnNames[j] + "\"" + ", ";
colValues += "'" + ((Object)fbreader[columnNames[j].ToString()]) + "', ";
}
else
{
columns += "\"" + columnNames[j] + "\"";
colValues += "'" + fbreader[columnNames[j].ToString()] + "' )";
}
j++;
}
string insertQuery = "INSERT INTO Data." + tableName + " (" + columns + ") VALUES " + colValues;
using (SqlConnection sqlconn = getSqlConncetion())
{
try
{
SqlCommand sqlcmd = new SqlCommand(insertQuery, sqlconn);
sqlcmd.ExecuteNonQuery();
sqlconn.Close();
insertedCount++;
}
catch (Exception ex)
{
notInsertedCount++;
//MessageBox.Show("Not Inserted-->" + ex.Message);
//listBox1.Items.Add(fbreader["CO_CODE"] + ex.Message);
}
}
}
fbreader.Close();
}
}
listBox1.Items.Add(insertedCount + " Rows are Updated....");
if (notInsertedCount > 0)
{
listBox1.Items.Add(notInsertedCount + " Rows are not Updated....");
listBox1.Items.Add("....");
}
else
{
listBox1.Items.Add("....");
}
//MessageBox.Show(insertedCount + " Rows are Updated in IBDMaster table " + tableName);
fbconn.Close();
}
return;
}
First, I want to skip or ignore the error I'm getting.
Second, the database code is performing slowly, is there any method to do a fast update to the database.

ASP.NET Core issues with DB2 queries in IIS

I'm working on a web app in ASP.Net Core v1.0 in VS2015. The premise of this application is simply to retrieve information from our DB2 database and display it for our dispatchers to use. The issue I'm running into is while on my development PC the application runs fine in IIS Express but once deployed I get the following error:
Index (zero based) must be greater than or equal to zero.
So I know that my query is coming back with no results, I have tried changing settings in IIS but I can't seem to get this to work. The results are retrieved and displayed correctly when debugging on my PC. Also this is the code behind of the retrieving controller:
public ViewResult EvvCityFull()
{
DB2Command myDB2Command = null;
string myDb2ConnectionString = "Server=Server;Database=DB;UID=User;PWD=Pass;";
DB2Connection myDb2Connection = new DB2Connection(myDb2ConnectionString);
myDb2Connection.Open();
myDB2Command = myDb2Connection.CreateCommand();
myDB2Command.CommandText = "SELECT DISTINCT FINAL_DRIVERS.DRIVER_ID, FINAL_DRIVERS.NAME, FINAL_DRIVERS.STATUS, FINAL_DRIVERS.REMAINING_HOURS, FINAL_DRIVERS.LAST_SAT_LOC, FINAL_DRIVERS.LAST_SAT_DATE FROM " +
"(" +
"SELECT BASE_DRIVERS.DRIVER_ID, BASE_DRIVERS.NAME, BASE_DRIVERS.STATUS, BASE_DRIVERS.REMAINING_HOURS, BASE_DRIVERS.LAST_SAT_LOC, BASE_DRIVERS.LAST_SAT_DATE, DATA AS EMPLOYMENT " +
"FROM " +
"(" +
"SELECT BOARD_DRIVERS.DRIVER_ID, BOARD_DRIVERS.NAME, BOARD_DRIVERS.STATUS, BOARD_DRIVERS.REMAINING_HOURS, BOARD_DRIVERS.LAST_SAT_LOC, BOARD_DRIVERS.LAST_SAT_DATE, DATA AS CITY " +
"FROM " +
"(" +
"SELECT DRIVER_ID, NAME, STATUS, REMAINING_HOURS, LAST_SAT_LOC, LAST_SAT_DATE, DATA AS BOARD FROM TMWIN.DRIVER, TMWIN.CUSTOM_DATA " +
"WHERE DRIVER_ID = SRC_TABLE_KEY " +
"AND ACTIVE_IN_DISP = 'True' " +
"AND CUSTDEF_ID = 6 " +
"AND DATA IN('CITY') " +
"AND REMAINING_HOURS IS NOT NULL " +
"AND STATUS IS NOT NULL " +
") BOARD_DRIVERS, " +
"TMWIN.CUSTOM_DATA " +
"WHERE BOARD_DRIVERS.DRIVER_ID = SRC_TABLE_KEY " +
"AND CUSTDEF_ID = 7 " +
"AND DATA IN('EVANSVILLE') " +
") BASE_DRIVERS, " +
"TMWIN.CUSTOM_DATA " +
"WHERE BASE_DRIVERS.DRIVER_ID = SRC_TABLE_KEY " +
"AND CUSTDEF_ID = 9 " +
"AND DATA IN('FULL-TIME') " +
") FINAL_DRIVERS LEFT JOIN TMWIN.CUSTOM_DATA " +
"ON FINAL_DRIVERS.DRIVER_ID = SRC_TABLE_KEY ORDER BY FINAL_DRIVERS.DRIVER_ID ASC";
DB2DataReader myDb2DataReader = null;
List<Driver> result = new List<Driver>();
using (myDb2DataReader = myDB2Command.ExecuteReader())
{
while (myDb2DataReader.Read())
{
Driver driver = new Driver();
driver.DRIVER_ID = myDb2DataReader["DRIVER_ID"].ToString();
driver.NAME = myDb2DataReader["NAME"].ToString();
driver.STATUS = myDb2DataReader["STATUS"].ToString();
driver.REMAINING_HOURS = Convert.ToDouble(myDb2DataReader["REMAINING_HOURS"].ToString());
driver.LAST_SAT_LOC = myDb2DataReader["LAST_SAT_LOC"].ToString();
driver.LAST_SAT_DATE = Convert.ToDateTime(myDb2DataReader["LAST_SAT_DATE"].ToString());
result.Add(driver);
}
}
myDb2DataReader.Close();
myDB2Command.Dispose();
myDb2Connection.Close();
ViewBag.Drivers = result;
return View(ViewBag.Drivers);
}
I cannot figure out the difference in the environments that makes this query work and return the appropriate data on my machine but fails to return anything when deployed. If anyone has any answers for me it'd be greatly appreciated, thank you.

I want to insert multiple rows into SQL Server database, but get syntax errors

I want to insert multiple pieces of data into a SQL Server database as shown below, but when I run this code, I get a syntax error
Incorrect syntax near the keyword 'union'.
Incorrect syntax near ''.
Incorrect syntax near ''.
Incorrect syntax near ''.
Code:
SqlCommand cmd2 = new SqlCommand("INSERT INTO [rampDB].[dbo].[Answers]([AssessmentID],[questionID],[result],[comment]) SELECT('"
+ assessmentid + "1.1a" + RadioButtonList1.SelectedItem.Value.ToString() + TextBox1.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1b" + RadioButtonList2.SelectedItem.Value.ToString() + TextBox2.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1c" + RadioButtonList3.SelectedItem.Value.ToString() + TextBox3.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1d" + RadioButtonList4.SelectedItem.Value.ToString() + TextBox4.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1e" + RadioButtonList5.SelectedItem.Value.ToString() + TextBox5.Text
+ "')", sqlConn);
Multiple-insert syntax for SQL Server is possible with only INSERT, like so:
INSERT INTO rampDB.dbo.Answers (
assessmentID, QuestionId, Result, Comment
) VALUES
( #r1v1, #r1v2, #r1v3, #r1v4 ),
( #r2v1, #r2v2, #r2v3, #r2v4 ),
( #r3v1, #r3v2, #r3v3, #r3v4 )
That said, the best way is to use a single INSERT with parameters, which is then executed for each row.
Relpace "'union'" with this--> "union"

Insert or Update in one statement for access db

I am trying to wirte an sql statement such that I can either update (if record already exists) or insert a data record into an access db via an OleDBCommand.
sql statement:
string sql = "IF EXISTS (SELECT * FROM tblMitarbeiter_Arbeitsform WHERE (fkLogin = '" + _Login.ToUpper() + "') AND (fkIdArbeitsform = " + dr.fkIdArbeitsform + "))";
sql += " UPDATE tblMitarbeiter_Arbeitsform SET (Prozent = " + dr.Prozent + ")";
sql += " WHERE (fkLogin = '" + _Login.ToUpper() + "') AND (fkIdArbeitsform = " + dr.fkIdArbeitsform + ")";
sql += " ELSE INSERT INTO tblMitarbeiter_Arbeitsform (fkLogin, fkIdArbeitsform, Prozent) VALUES ('" + _Login.ToUpper() + "', " + dr.fkIdArbeitsform + ", " + dr.Prozent + ")";
oCmd = new OleDbCommand(sql, getOekobonusConnection());
oCmd.ExecuteScalar();
//oCmd.ExecuteNonQuery();
both ExecuteScalar and ExecuteNonQuery are not working. What am I doing wrong?
There's no control of flow constructs in Access SQL so you can't do an IF. You would have to split the logic and do the test in your code, then issue an update or insert accordingly.

Categories