Postgresql - Create Database & Table dynamically - c#

This code is not working. Can anyone direct me where I can find examples of creating a Postgresql database and table on the fly with C#?
const string connStr = "Server=localhost;Port=5432;
User Id=postgres;Password=enter;Database=postgres";
var m_conn = new NpgsqlConnection(connStr);
// creating a database in Postgresql
m_createdb_cmd = new NpgsqlCommand("CREATE DATABASE IF NOT EXISTS \"testDb\" " +
"WITH OWNER = \"postgres\" " +
"ENCODING = 'UTF8' " +
"CONNECTION LIMIT = -1;", m_conn);
// creating a table in Postgresql
m_createtbl_cmd = new NpgsqlCommand(
"CREATE TABLE MyTable(CompanyName VARCHAR(150))";
m_conn.Open();
m_createdb_cmd.ExecuteNonQuery();
m_createtbl_cmd.Connection = m_conn;
m_conn.Close();
The db is created but I get a silent fail on creating the table.

I would do this:
string connStr = "Server=localhost;Port=5432;User Id=postgres;Password=enter;";
var m_conn = new NpgsqlConnection(connStr);
var m_createdb_cmd = new NpgsqlCommand(#"
CREATE DATABASE IF NOT EXISTS testDb
WITH OWNER = postgres
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;
", m_conn);
m_conn.Open();
m_createdb_cmd.ExecuteNonQuery();
m_conn.Close();
connStr = "Server=localhost;Port=5432;User Id=postgres;Password=enter;Database=testDb";
m_conn = new NpgsqlConnection(connStr);
m_createtbl_cmd = new NpgsqlCommand(
"CREATE TABLE table1(ID CHAR(256) CONSTRAINT id PRIMARY KEY, Title CHAR)"
, m_conn);
m_conn.Open();
m_createtbl_cmd.ExecuteNonQuery();
m_conn.Close();
The use of var here is not recommended. I used it as I don't know what are the returned types but you should.
Notice the use of a raw string (#). It makes string building simple.
Do not use identifiers surrounded by double quotes in Postgresql unless the identifier is otherwise illegal. It will make you life much harder.

seems like you simply forget to invoke ExecuteNonQuery method of m_createtbl_cmd:
m_createtbl_cmd.ExecuteNonQuery();
Also you can simplify it using DynORM library: http://dynorm.codeplex.com/
Hope it helps!

This is what worked for me to verify the existence of any Postgres database with C#:
private bool chkDBExists(string connectionStr, string dbname)
{
using (NpgsqlConnection conn = new NpgsqlConnection(connectionStr))
{
using (NpgsqlCommand command = new NpgsqlCommand
($"SELECT DATNAME FROM pg_catalog.pg_database WHERE DATNAME = '{dbname}'", conn))
{
try
{
conn.Open();
var i = command.ExecuteScalar();
conn.Close();
if (i.ToString().Equals(dbname)) //always 'true' (if it exists) or 'null' (if it doesn't)
return true;
else return false;
}
catch (Exception e) { return false; }
}
}
}
** The if used in the try-catch statement could simply check if the return of the ExecuteScalar is null for non-existent DB and not-null if it exists.

You can pass the ConnectionString to this function :
private static string GetConnectionString(string postgreSqlConnectionString)
{
NpgsqlConnectionStringBuilder connBuilder = new()
{
ConnectionString = postgreSqlConnectionString
};
string dbName = connBuilder.Database;
var masterConnection = postgreSqlConnectionString.Replace(dbName, "postgres");
using (NpgsqlConnection connection = new(masterConnection))
{
connection.Open();
using var checkIfExistsCommand = new NpgsqlCommand($"SELECT 1 FROM pg_catalog.pg_database WHERE datname = '{dbName}'", connection);
var result = checkIfExistsCommand.ExecuteScalar();
if (result == null)
{
using var command = new NpgsqlCommand($"CREATE DATABASE \"{dbName}\"", connection);
command.ExecuteNonQuery();
}
}
postgreSqlConnectionString = masterConnection.Replace("postgres", dbName);
return postgreSqlConnectionString;
}
This will retrieve dbname from ConnectionString then checks if it already exists or not. if it didn't exist it will create one with the given dbname.
You should use above function in ConfigureServices of Startup class like this :
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
{
options.UseNpgsql(GetConnectionString(Configuration["YourConnectionString"]));
});
}

Solution:
// 1. Connect to server to create database:
const string connStr = "Server=localhost;Port=5432;User Id=postgres;Password=enter;";
// 2. Connect to server to create table:
const string connStr2 = "Server=localhost;Port=5432;User Id=postgres;Password=enter;Database=testDb";
var m_conn = new NpgsqlConnection(connStr); // db connction
var m_conn2 = new NpgsqlConnection(connStr2); // table connection
// creating a database in Postgresql
m_createdb_cmd = new NpgsqlCommand("CREATE DATABASE IF NOT EXISTS \"testDb\" " +
"WITH OWNER = \"postgres\" " +
"ENCODING = 'UTF8' " +
"CONNECTION LIMIT = -1;", m_conn);
// creating a table in Postgresql
m_createtbl_cmd = new NpgsqlCommand
{
CommandText ="CREATE TABLE table1(ID CHAR(256) CONSTRAINT id PRIMARY KEY, Title CHAR)"
};
m_createtbl_cmd.Connection = m_conn2;
// 3.. Make connection and create
// open connection to create DB
m_conn.Open();
m_createdb_cmd.ExecuteNonQuery();
m_conn.Close();
// open connection to create table
m_conn2.Open();
m_createtbl_cmd.ExecuteNonQuery();
m_conn2.Close();
This works but is there a shorter way to do this? I had to create two Npgsql connections. I don't know, just doesn't look very elegant to me.

Related

Querying SQL Tables if they exists. Delete contents of table if they do Create table if if they don't

I am making a simple C# program that pulls out folder names and file names and puts them into a SQL Database.
I am making a method in which I would like if these exist to be checked. However Instead of dropping the whole table I would rather just delete the items in it. And if it does not exist to create the table.
This is what I have so far but it does not seem to be deleting the table regardless.
Any help is appreciated.
static void CheckTablesExist() {
try {
// Build connection string
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder {
DataSource = "WIN10-LAP-HJP",
UserID = "sa",
Password = "Mypassword123",
InitialCatalog = "SAPExtract"
};
// Connect to SQL
Console.Write("Connecting to SQL Server ... ");
using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) {
Console.WriteLine("Done.");
Console.WriteLine("Checking If table dbo.FolderInfo");
string queryCheckTable = "DROP TABLE IF EXISTS dbo.Product";
using (SqlCommand command = new SqlCommand(queryCheckTable, connection)) {
command.Parameters.Add("#FolderID", SqlDbType.UniqueIdentifier).Value = "dbo.FolderInfo";
connection.Open();
}
}
}
catch (SqlException e) {
Console.WriteLine(e.ToString());
}
}
UPDATED to execute
static void CheckTablesExist()
{
try
{
// Build connection string
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder
{
DataSource = "WIN10-LAP-HJP",
UserID = "sa",
Password = "Mypassword123",
InitialCatalog = "SAPExtract"
};
// Connect to SQL
Console.Write("Connecting to SQL Server ... ");
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
Console.WriteLine("Done.");
Console.WriteLine("Checking If table dbo.FolderInfo");
string queryCheckTable = "DROP TABLE IF EXISTS #FolderTable";
using (SqlCommand command = new SqlCommand(queryCheckTable, connection))
{
command.Parameters.Add("#FolderTable", SqlDbType.NVarChar).Value = "dbo.FolderInfo";
connection.Open();
var result = command.ExecuteNonQuery();
// Check Error
if (result < 0)
Console.WriteLine("Error inserting data into Database!");
}
}
}
catch (SqlException e)
{
Console.WriteLine(e.ToString());
}
}
You could modify the query for queryCheckTable to:
IF (OBJECT_ID('Your_Table_Name','U') IS NULL)
BEGIN
--Add "TRUNCATE TABLE" query here
--Note: Use "TRUNCATE" or "DELETE" instead of "DROP"
END
ELSE
BEGIN
--Add "CREATE TABLE" query here
END

Database Deleting Rows

so this is my code
for (int i = 0; i < users_table.RowCount; ++i)
{
SQLDatabase.DatabaseRow row = users_table.GetRow(i); //get current ID.
if (userID == users_table.GetRow(i)["ID"]) //if userID is the same as it's in the row
{
row["ID"] = "0";
row["Name"] = "DELETED";
row["Username"] = "DELETED";
row["Password"] = "DELETED";
row["UserType"] = "DELETED";
row["LastLoginDate"] = "0";
row["LastLoginTime"] = "0";
users_table.Update(row);
}
}
My goal is to delete a row. Sadly I'm unable to insert NULL values etc., any idea how I could delete that row? I would like to add that I do not have .delete functions or anything in particular. I would be glad if you could tell me how to add them.
Thanks.
(This answer assumes you're using SQL Server)
You can easily execute SQL Commands using System.Data.SqlClient.
The connection string would be the connection details to your database instance. You can see some more examples of how to construct your connection string # Connection String Examples. Also, when you're deleting rows from your database you want to utilize the DELETE command not the UPDATE. More details can be found on DELETE (Transact-SQL)
public void deleteRow()
{
string connectionString = "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password = myPassword; ";
string queryString = "DELETE FROM Test_Table WHERE ID = 5";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}

MySQL connection throws null reference

My MySQL connection throws null reference although this code worked well one year ago.
The line where the debugger indicates the exception contains
"connection = new MySqlConnection(connectionString);":
DBConnect MySqlConnection = new DBConnect();
string[] resultArray = MySqlConnection.GetValidUser(
"tbl_user",
tbEmail.Text,
tbPassword.Text
);
//THROWS null reference exception in method 'private bool OpenConnection()'
//A first chance exception of type 'System.ArgumentException' occurred in System.Data.dll
This is my DBConnect class:
class DBConnect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
public DBConnect()
{
server = "x.x.x.x";
database = "...";
uid = "...";
password = "...";
string connectionString = "SERVER=" + server + ";" +
"DATABASE=" + database + ";" +
"UID=" + uid + ";" +
"PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
}
private bool OpenConnection()
{
try
{
connection.Open();
return true;
}
catch (MySqlException ex)
{
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to MySQL server.");
break;
case 1045:
MessageBox.Show("Invalid username or password.");
break;
}
return false;
}
}
public string[] GetValidUser(string dbTable, string dbUsername, string dbPassword)
{
string query = "SELECT id,email,password FROM " + dbTable +
" WHERE email='" + dbUsername +
"' AND password='" + dbPassword + "'";
string[] resultArray = new string[3];
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
resultArray[0] = dataReader.GetInt32(0).ToString();
resultArray[1] = dataReader.GetString(1);
resultArray[2] = dataReader.GetString(2);
}
dataReader.Close();
this.CloseConnection();
}
return resultArray;
}
}
The original code for the database class can be found here.
This is not an answer to the NullReferenceException - we're still working through that in the comments; this is feedback for the security parts.
The first thing we can look at is SQL injection; this is very easy to fix - see below (note I've tidied some other things too)
// note: return could be "bool" or some kind of strongly-typed User object
// but I'm not going to change that here
public string[] GetValidUser(string dbUsername, string dbPassword)
{
// no need for the table to be a parameter; the other two should
// be treated as SQL parameters
string query = #"
SELECT id,email,password FROM tbl_user
WHERE email=#email AND password=#password";
string[] resultArray = new string[3];
// note: it isn't clear what you expect to happen if the connection
// doesn't open...
if (this.OpenConnection())
{
try // try+finally ensures that we always close what we open
{
using(MySqlCommand cmd = new MySqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("email", dbUserName);
// I'll talk about this one later...
cmd.Parameters.AddWithValue("password", dbPassword);
using(MySqlDataReader dataReader = cmd.ExecuteReader())
{
if (dataReader.Read()) // no need for "while"
// since only 1 row expected
{
// it would be nice to replace this with some kind of User
// object with named properties to return, but...
resultArray[0] = dataReader.GetInt32(0).ToString();
resultArray[1] = dataReader.GetString(1);
resultArray[2] = dataReader.GetString(2);
if(dataReader.Read())
{ // that smells of trouble!
throw new InvalidOperationException(
"Unexpected duplicate user record!");
}
}
}
}
}
finally
{
this.CloseConnection();
}
}
return resultArray;
}
Now, you might be thinking "that's too much code" - sure; and tools exist to help with that! For example, suppose we did:
public class User {
public int Id {get;set;}
public string Email {get;set;}
public string Password {get;set;} // I'll talk about this later
}
We can then use dapper and LINQ to do all the heavy lifting for us:
public User GetValidUser(string email, string password) {
return connection.Query<User>(#"
SELECT id,email,password FROM tbl_user
WHERE email=#email AND password=#password",
new {email, password} // the parameters - names are implicit
).SingleOrDefault();
}
This does everything you have (including safely opening and closing the connection), but it does it cleanly and safely. If it method returns a null value for the User, it means no match was found. If a non-null User instance is returned - it should contain all the expected values just using name-based conventions (meaning: the property names and column names match).
You might notice that the only code that remains is actually useful code - it isn't boring plumbing. Tools like dapper are your friend; use them.
Finally; passwords. You should never store passwords. Ever. Not even once. Not even encrypted. Never. You should only store hashes of passwords. This means that you can never retrieve them. Instead, you should hash what the user supplies and compare it to the pre-existing hashed value; if the hashes match: that's a pass. This is a complicated area and will require significant changes, but you should do this. This is important. What you have at the moment is insecure.
Among other things, it sounds like you have problems with the connection string - from comments:
While "connection = new MySqlConnection(); connection.ConnectionString = connectionString;" throws an exception the statement "connection = new MySqlConnection();" does not...
The difference here is simply: in the latter you aren't setting the connection string - so it sounds like your connection string is not correctly escaping the values (most likely, the password); you could try:
var cs = new DbConnectionStringBuilder();
cs["SERVER"] = server;
cs["DATABASE"] = database;
cs["UID"] = uid;
cs["PASSWORD"] = password;
var connectionString = cs.ConnectionString;

how to reference columns in sql server connection in C#

I'm trying to translate some perl code into C# and I'm having some trouble with the following.
After establishing a sql server connection and executing the select statement, how do I reference the different elements in the table columns. For example, in Perl it looks like:
my $dbh = DBI -> connect( NAME, USR, PWD )
or die "Failed to connect to database: " . DBI->message;
my $dbname = DB_NAME;
my $dbschema = DB_SCHEMA;
my $sql = qq{select a,b,c,d,e,f,g,h,i,...
from $dbname.$dbschema.package p
join $dbname.$dbschema.package_download pd on p.package_id = pd.package_id
join $dbname.$dbschema.download d on pd.download_id = d.download_id
where p.package_name = '$package'
--and ds.server_address like 'tcp/ip'
order by a,b,c,d,..};
my $sth = $dbh -> prepare( $sql )
or die "Failed to prepare statement: " . $dbh->message;
$sth -> execute()
or die "Failed to execute statement: " . $sth->message;
#now to go through each row in result table
while ( #data = $sth->fetchrow_array() )
{
print "$data[0]";
# If source server FTP is not already open, make new FTP
if ( $data[0] != $src_id )
{
if ( $src_ftp )
{ $src_ftp -> quit; }
$src_ftp = make_ftp( $data[1], $data[2], $data[3], $data[18], $data[19], $data[20] );
$src_id = $data[0];
}
}
so far I've got it down to
string db = NAME;
string myConnectionString = "Data Source=ServerName;" + "Initial Catalog=" + db + "User id=" + ODBC_USR + "Password=" + PWD
SqlConnection myConnection = new SqlConnection(myConnectionString);
string myInsertQuery = "select a,b,c,d,e,f,g,h,i,...
from $dbname.$dbschema.package p
join $dbname.$dbschema.package_download pd on p.package_id = pd.package_id
join $dbname.$dbschema.download d on pd.download_id = d.download_id
where p.package_name = '$package'
--and ds.server_address like 'tcp/ip'
order by a,b,c,d,..";
SqlCommand myCommand = new SqlCommand(myInsertQuery);
myCommand.Connection = myConnection;
myConnection.Open();
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
but how do I reference the columns like data[0] and data[1] in C#. Sorry I'm new to both languages so my background is severely lacking. Thanks!
You could reference your column directly by its column name or by numeric order (it starts with 0 as the first column) either through a DataTable, DataSet, DataReader or a specific DataRow.
For the sake of example i'll use a DataTable here and I will name it as dt and let's say we want to reference the first row then you could reference it with the following Syntax/Format:
dt[RowNumber]["ColumnName or Column Number"].ToString();
For example:
dt[0]["a"].ToString();
Or by number the first column with be 0 like:
dt[0][0].ToString();
And use Parameters by the way because without which it would be susceptible to SQL Injection. Here's a more complete code below:
string db = NAME;
string myConnectionString = "Data Source=ServerName;" + "Initial Catalog=" + db + "User id=" + ODBC_USR + "Password=" + PWD
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
string mySelectQuery = #"SELECT a,b,c,d,e,f,g,h,i,...
FROM package p
JOIN package_download pd on p.package_id = pd.package_id
join download d on pd.download_id = d.download_id
WHERE p.package_name = #PackageName
AND ds.server_address LIKE 'tcp/ip%'
ORDER by a,b,c,d";
try
{
connection.Open();
using (SqlDataAdapter da = new SqlDataAdapter(mySelectQuery, connection))
{
using (SqlCommand cmd = new SqlCommand())
{
da.SelectCommand.Parameters.AddWithValue("#PackageName", txtPackage.Text);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count>0) // Make sure there is something in your DataTable
{
String aVal = dt[0]["a"].ToString();
String bVal = dt[0]["b"].ToString();
// You'll be the one to fill up
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I change your LIKE 'tcp/ip' to LIKE 'tcp/ip%' by the way which is the more appropriate one of using LIKE.
you can use ado.net entity data table to reference the tables in your sql server. I don't know if you're asking exactly this but it may help. because direct referencing to sql server is not possible as far as i know.

Object reference not set to an instance of object

I have a function like this
public void GetTablesWithUpperCaseName()
{
SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
objConnectionString.DataSource = txtHost.Text;
objConnectionString.UserID = txtUsername.Text;
objConnectionString.Password = txtPassword.Text;
objConnectionString.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue);
SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString);
//To Open the connection.
sConnection.Open();
//Query to select table_names that have their names in uppercase letters.
string selectTablesWithUppercaseName = #"SELECT
NAME
FROM
sysobjects
WHERE
UPPER(name) COLLATE Latin1_General_BIN = name COLLATE Latin1_General_BIN
AND
OBJECTPROPERTY(ID,N'IsTable')=1
AND
OBJECTPROPERTY(ID,N'IsMSShipped')=0 ";
//Create the command object
SqlCommand sCommand = new SqlCommand(selectTablesWithUppercaseName, sConnection);
try
{
//Create the dataset
DataSet dsListOfTablesWithUppercaseName = new DataSet("sysobjects");
//Create the dataadapter object
SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectTablesWithUppercaseName, sConnection);
//Provides the master mapping between the sourcr table and system.data.datatable
sDataAdapter.TableMappings.Add("Table", "sysobjects");
//Fill the dataset
sDataAdapter.Fill(dsListOfTablesWithUppercaseName);
//Bind the result combobox with foreign key table names
DataViewManager dvmListOfForeignKeys = dsListOfTablesWithUppercaseName.DefaultViewManager;
dgResultView.DataSource = dsListOfTablesWithUppercaseName.Tables["sysobjects"];
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog log = new EventLog("Application");
log.Source = "MFDBAnalyser";
log.WriteEntry(ex.Message);
}
finally
{
//If connection is not closed then close the connection
if(sConnection.State != ConnectionState.Closed)
{
sConnection.Close();
}
}
}
And another function for counting the rows generated from the previous functions. But this function
Null Reference Exception or Object
reference not set to an instance of
object..
Can anyone help me in this... why it is catching error only for the functions above and working fine for all other similar functions.
private void UpdateLabelText()
{
SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
objConnectionString.DataSource = txtHost.Text;
objConnectionString.UserID = txtUsername.Text;
objConnectionString.Password = txtPassword.Text;
objConnectionString.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue);
SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString);
//To Open the connection.
sConnection.Open();
try
{
int SelectedCellTotal = 0;
int counter;
// Iterate through the SelectedCells collection and sum up the values.
for(counter = 0;counter < (dgResultView.SelectedCells.Count);counter++)
{
if(dgResultView.SelectedCells[counter].FormattedValueType == Type.GetType("System.String"))
{
string value = null;
// If the cell contains a value that has not been commited,
if(dgResultView.IsCurrentCellDirty == true)
{
value = dgResultView.SelectedCells[counter].EditedFormattedValue.ToString();
}
else
{
value = dgResultView.SelectedCells[counter].FormattedValue.ToString();
}
if(value != null)
{
// Ignore cells in the Description column.
if(dgResultView.SelectedCells[counter].ColumnIndex != dgResultView.Columns["TABLE_NAME"].Index)
{
if(value.Length != 0)
{
SelectedCellTotal += int.Parse(value);
}
}
}
}
}
// Set the labels to reflect the current state of the DataGridView.
lblDisplay.Text = "There are Total " + dgResultView.RowCount + cmbOperations.SelectedItem.ToString();
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog log = new EventLog("Application");
log.Source = "MFDBAnalyser";
log.WriteEntry(ex.Message);
}
finally
{
//If connection is not closed then close the connection
if(sConnection.State != ConnectionState.Closed)
{
sConnection.Close();
}
}
}
Also the lblDisplay.Text is not taking proper spaces.
Waiting for reply
OK, I don't really have an answer why you're getting a "null reference exception" - but a few points to throw in, nonetheless:
I would use sys.tables instead of sysobjects and having to specify what type of object to query for
ALWAYS put your disposable SqlConnection and SqlCommand into using(.....) { ...... } blocks. That way, you won't need any finally {..} blocks, and .NET will take care of properly disposing of those objects when they're no longer needed
why do you use a DataSet when you only have a single table inside?? That's just unnecessary overhead - use a DataTable instead!
don't open the SqlConnection that early - wait 'til the very last moment, open it, execute query, close it again right away
actually, when using the SqlDataAdapter, you don't need to open the SqlConnection yourself at all - the SqlDataAdapter will do that for you (and close it again after it is done reading the data)
do not mix the retrieval of the data from the database with the binding to the UI element - this is a very bad practice. From the GetTablesWithUpperCaseName method, you should return something (like a DataTable) to the caller (the UI) and let the UI handle the binding process
along the same lines: that method should not be grabbing stuff from UI elements (like text boxes) itself - pass in those values as method parameters, to get a cleaner code - one that you might actually be able to reuse in another project some day
This is how I think your first method ought to look like
public DataTable GetTablesWithUpperCaseName(string server, string database,
string username, string password)
{
// Create the datatable
DataTable dtListOfTablesWithUppercaseName = new DataTable("tableNames");
SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
objConnectionString.DataSource = server;;
objConnectionString.UserID = username;
objConnectionString.Password = password;
objConnectionString.InitialCatalog = database;
// Define the Query against sys.tables - much easier and cleaner!
string selectTablesWithUppercaseName =
"SELECT NAME FROM sys.tables WHERE UPPER(name) COLLATE Latin1_General_BIN = name COLLATE Latin1_General_BIN AND is_msshipped = 0";
// put your SqlConnection and SqlCommand into using blocks!
using (SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString))
using (SqlCommand sCommand = new SqlCommand(selectTablesWithUppercaseName, sConnection))
{
try
{
// Create the dataadapter object
SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectTablesWithUppercaseName, sConnection);
// Fill the datatable - no need to open the connection, the SqlDataAdapter will do that all by itself
// (and also close it again after it is done)
sDataAdapter.Fill(dtListOfTablesWithUppercaseName);
}
catch (Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog log = new EventLog("Application");
log.Source = "MFDBAnalyser";
log.WriteEntry(ex.Message);
}
}
// return the data table to the caller
return dtListOfTablesWithUppercaseName;
}

Categories

Resources