Retrieve List of Tables from Specific Database on Server C# - c#

How can one retrieve the tables' names into a List<string> from a specific database on a server?

System.Data.SqlClient has what you need without a formal query on sys.Tables (though that's what it's using in the background). Use the GetSchema() method on the SqlConnection object and designate that you want the "Tables" and it will send you a DataTable object back with a row for each table. It sends back database name, table schema name, table name, and table type in each row (in that column order). The code would look like this:
public static List<string> GetTables(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
DataTable schema = connection.GetSchema("Tables");
List<string> TableNames = new List<string>();
foreach (DataRow row in schema.Rows)
{
TableNames.Add(row[2].ToString());
}
return TableNames;
}
}

For SQL Server 2005 and higher:
using (SqlConnection connection = new SqlConnection(#"Data Source=(local);Integrated Security=True;Initial Catalog=DB_Name;")) {
connection.Open();
using (SqlCommand command = connection.CreateCommand()) {
command.CommandText =
#"SELECT s.name, o.name
FROM sys.objects o WITH(NOLOCK)
JOIN sys.schemas s WITH(NOLOCK)
ON o.schema_id = s.schema_id
WHERE o.is_ms_shipped = 0 AND RTRIM(o.type) = 'U'
ORDER BY s.name ASC, o.name ASC";
using (SqlDataReader reader = command.ExecuteReader()) {
while (reader.Read()) {
string schemaName = reader.GetString(0);
string tableName = reader.GetString(1);
// your code goes here...
}
}
}
}

To fetch all the user defined tables from the DB ( SQlServer), we have to query system catalogs.
SELECT Name from Sysobjects where xtype = 'u'
this query will return all the user defined tables in the DataBase

I think that this SQL should return a table containing tableNames in your DB:
SELECT * FROM information_schema.tables

You can use LINQ query to get all tables name fairly easily:
public List<string> GetSqlTables(SqlConnection conn)
=> (from DataRow row in conn.GetSchema("Tables").Rows.Cast<DataRow>()
select row["TABLE_NAME"].ToString()).ToList();

.Net Core extension using SqlConnection that opens/closes the connection.
public static class SQLExtensions
{
public static List<string> GetTableNames(this SqlConnection connection)
{
using (connection)
{
connection.Open();
return connection.GetSchema("Tables")
.Rows
.Cast<DataRow>()
.Select(row => row["TABLE_NAME"].ToString())
.OrderBy(nme => nme)
.ToList();
} // Auto Close exiting the block
}
}
Usage (Linqpad)
var connectionStr = #"Data Source=.;Integrated Security=SSPI;Initial Catalog=Rasa";
(new SqlConnection(connectionStr).GetTableNames()).Dump();

this my solution:
public void opencon()
{
if (conn == null)
{
conn = new SqlConnection(#"Your connection");
}
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
}
public void Closecon()
{
if ((conn != null) && (conn.State == ConnectionState.Open))
{
conn.Close();
}
}
public void GetTables(ComboBox cb)
{
chuoiketnoi();
DataTable schema = conn.GetSchema("Tables");
foreach (DataRow row in schema.Rows)
{
cb.Items.Add(row[2].ToString());
}
dongketnoi();
}

Related

How do I return a table from a SQL query as a List in C#?

I have a Xamarin app that connects to a SQL Server (*), and I want to insert the data from the SQL Server's tables into a local SQLite database. My approach is to execute a query like
select * from Table1
retrieve the results of the query as a List, then insert that List into my SQLite table. That said I'm very new at using SqlClient, so please share if there are better ways to do this. Thanks.
Edit: the smallest number of columns these tables have is 5. Don't know if that disqualifies Lists as the best option.
My code:
private void LoadData()
{
string cs = #"connection string here";
using (SqlConnection sconn = new SqlConnection(cs))
{
sconn.Open();
SqlDataReader reader = null;
SqlCommand aml = new SqlCommand("select * from Table1");
reader = aml.ExecuteReader();
while (reader.Read())
{
// get result of query as List somehow?
}
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
// insert the list object
}
}
}
}
(*) The app does not use a web service as the app is intended for onsite use only and will not be distributed publicly.
A better alternative way to do it more easier is to use a ORM like dapper
With the help of dapper, all you need to do is
using (var connection = new SqlConnection(_sqlConnectionString))
{
var results = connection.Query<YourTableModel>(query).ToList();
return results;
}
You can get data from the SQL Server as DataTable or convert it to a list as you prefer.
public DataTable GetDataTable(string connectionString, string tableName)
{
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
string query = $'SELECT * FROM [{tableName}]';
SqlCommand cmd = new SqlCommand(query, conn);
DataTable t1 = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
a.Fill(t1);
}
return t1;
}
Then use this table or list returned from the above method to insert in the SQLite table.
string cs = #"Data Source=datasource;Initial Catalog=databasename;User ID=user;Password=password";
DataTable table = GetDataTable(cs, "Table1");
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<Table1>();
if (conn.Query<Table1>("select * from Table1").Count() <= 0)
{
foreach(DataRow row in table.Rows)
{
//Access values of each row column row["columnName"]
// insert the list object
}
}
}
Refer to this one:
Inserting Data from SQL Server to Sqlite

is there is a way to print the database query result using SQLConnection

I am creating a SQLConnection to access some data. I need to print the entire DB result in log
I can able to print the specific cell value by referring out the cell, but I want to print the query result at single shot
string queryString = "select top 1 column_1, column_2 from master_table";
using (SqlConnection dbConnection = new SqlConnection(envDBConnectionString))
{
SqlCommand dbCommand = new SqlCommand(queryString, dbConnection);
dbConnection.Open();
SqlDataReader dbReader = dbCommand.ExecuteReader();
if (dbReader.HasRows)
{
while (dbReader.Read())
{
string col1Value = dbReader.GetValue(0).ToString());
string col2Value = dbReader.GetValue(1).ToString());
}
}
dbReader.Close();
dbConnection.Close();
}
Here I am getting each column value and stores it to string variable. instead I want to store the entire query result in that string
I suggest method extracting, i.e.
// Given a query, return records
private static IEnumerable<IDataRecord> QueryLines(string query) {
using (SqlConnection con = new SqlConnection(envDBConnectionString)) {
con.Open();
using (var q = new SqlCommand(query, con)) {
using (var reader = q.ExecuteReader()) {
while (reader.Read())
yield return reader as IDataRecord;
}
}
}
}
Then we can easily use it:
string command =
#"select top 1
column_1 as Column1,
column_2 as Column2
from master_table";
Having records, write them into a log in a desired format, e.g. simple CSV
File.AppendAllLines(#"c:\MyLog.txt", QueryLines(command)
.Select(record => $"{record[0]},{record[1]}"));
Or in elaborated XML
File.AppendAllLines(#"c:\MyLog.txt", QueryLines(command)
.Select(record => string.Concat(Enumerable
.Range(0, record.FieldCount)
.Select(i => $"<{record.GetName(i)}>{record[i]}</{record.GetName(i)}>")));
string queryString = "select top 1 column_1, column_2 from master_table";
using (SqlConnection dbConnection = new SqlConnection(envDBConnectionString))
{
SqlCommand dbCommand = new SqlCommand(queryString, dbConnection);
SqlDataAdapter sa = new SqlDataAdapter(dbCommand);
DataTable dt = new DataTable(); //All your data in this datatable
sa.fill(dt);
}
for reference:
Inside loop:
foreach(DataRow row in dt.rows){
row["COLUMN_NAME"].toString(); //or whatever datatype
}

How to return column names from SQL database

Question says it all really, I just want the all column names from a table, I'm looking for as basic way to do this as possible.
If you run the following SQL you'll get an empty rowset. From which you can interpret the column names by using a SqlCommand and DataReader.
using (var conn = new SqlConnection("your_conn_string"))
{
var command = new SqlCommand("select * from [dbo].[tableName] where 1 = 2");
conn.Open();
using(var dr = command.ExecuteReader())
{
var columns = new List<string>();
for(int i=0;i<reader.FieldCount;i++)
{
columns.Add(reader.GetName(i));
}
}
}
That depends entirely on the database. Almost all databases have some sort of metadata about the database. Most implement some version of the information_schema method.
For instance, a common way to get information about columns is:
select column_name
from information_schema.columns
where table_name = ? and table_schema = ?;
? are place-holders for the table name and schema.
This should do what you want.
public string[] getColumnsName()
{
List<string> listacolumnas=new List<string>();
using (SqlConnection connection = new SqlConnection(Connection))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "select c.name from sys.columns c inner join sys.tables t on t.object_id = c.object_id and t.name = 'Usuarios' and t.type = 'U'";
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
listacolumnas.Add(reader.GetString(0));
}
}
}
return listacolumnas.ToArray();
}
Get column name from SQL Server

How to truncate table when foreign dependencies exist via C#

For testing purposes I have a method that takes in a SqlConnection or a connection string and a string. The method examines the SqlConnection or the DbContext.Database.Connection.ConnectionString against a set of 'dangerous' strings, if the connection string has any 'dangerous' strings, it doesn't execute its query.
I basically need to know how to execute (via C#) a truncate/delete all data in table HOWEVER the problem is foreign dependencies. I am trying the following method. Remove all dependencies, delete the table and then reinstate all dependencies however I am having an issue with my reinstate all dependencies code. How can I do this via C#?
Main method that should delete the table.
public int DeleteFromDatabase(SqlConnection sqlConnection, string tableName)
{
int success = 0;
string sqlTrunc = "Delete from " + tableName;
if (isSafeSqlConnection(sqlConnection))
{
DropAllConstraints();
using (sqlConnection)
{
SqlCommand cmd = new SqlCommand(sqlTrunc, sqlConnection);
sqlConnection.Open();
success = cmd.ExecuteNonQuery();
sqlConnection.Close();
}
ReinstateAllConstraints(); //<=error happens here.
}
return success;
}
This drops all constraints:
public void DropAllConstraints()
{
string[] queries = File.ReadAllLines(#"Utility\UnsafeStrings\dropallcontraint.txt");
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
foreach (var item in queries)
{
var command = new SqlCommand(item, connection);
command.ExecuteNonQuery();
}
connection.Close();
}
}
This checks that the connection passed in isn't a live server:
private bool isSafeSqlConnection(SqlConnection connection)
{
string pathToUNsafeStrings = #"Utility\UnsafeStrings\UnsafeStrings.txt";
string[] unsafeStrings = File.ReadAllLines(pathToUNsafeStrings);
foreach (var item in unsafeStrings)
{
if (connection.ConnectionString.Contains(item))
return false;
}
return true;
}
This method essentially executes every entry returned from this query:
select
'ALTER TABLE dbo.' + object_name(fk.parent_object_id) +
' ADD CONSTRAINT ' + fk.name +
' FOREIGN KEY(' + c1.name + ') REFERENCES dbo.' +
object_name(fk.referenced_object_id) + '(' + c2.name + ')' as col1
from
sys.foreign_keys fk
inner join
sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
inner join
sys.columns c1 ON fkc.parent_column_id = c1.column_id and c1.object_id = fkc.parent_object_id
inner join
sys.columns c2 ON fkc.referenced_column_id = c2.column_id and c2.object_id = fkc.referenced_object_id
public void ReinstateAllConstraints()
{
string[] reinstateAllConstraints = File.ReadAllLines(#"Utility\UnsafeStrings\reisntateconstraint.txt");
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
foreach (var item in reinstateAllConstraints)
{
var command = new SqlCommand(item, connection);
command.ExecuteNonQuery();
}
connection.Close();
}
}
You can do this workflow:
Disable the foreign key check.
Delete all registers from tables that references the table that you want delete.
Delete all registers from table that you want delete.
Enable foreign key check.
You can see in this code below(I am using C# 6)
public bool TruncateTable(string tableName)
{
string sqlTrunc = $"Delete from {tableName}";
if (isSafeSqlConnection(sqlConnection))
{
DisableAllForeignKeys();
using (sqlConnection)
{
DeleteAllDependencies(tableName, sqlConnection);
SqlCommand cmd = new SqlCommand(sqlTrunc, sqlConnection);
sqlConnection.Open();
success = cmd.ExecuteNonQuery();
sqlConnection.Close();
}
EnableAllForeignKeys();
}
return success;
}
public void DisableAllForeignKeys(SqlConnection sqlConnection)
{
using(var command = new SqlCommand($"EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"", sqlConnection))
command.ExecuteNonQuery();
}
public void EnableAllForeignKeys(SqlConnection sqlConnection)
{
using(var command = new SqlCommand($"EXEC sp_msforeachtable \"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\"", sqlConnection))
command.ExecuteNonQuery();
}
private static void DeleteAllDependencies(string tableName, SqlConnection sqlConnection)
{
var sql =
$#"SELECT t.name AS 'Table that contains FK',
fk.name AS 'FK Name',
t1.Name AS 'Table that is being referenced'
FROM sys.foreign_key_columns fkc
INNER JOIN sys.tables t ON t.object_id = fkc.parent_object_id
INNER JOIN sys.tables t1 ON t1.object_id = fkc.referenced_object_id
INNER JOIN sys.columns c1 ON c1.object_id = fkc.parent_object_id AND c1.column_id = fkc.parent_column_id
INNER JOIN sys.foreign_keys fk ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.schemas sc ON t.schema_id = sc.schema_id
WHERE (sc.name + '.' +t1.name) = 'dbo.{
tableName}';";
var command = sqlConnection.CreateCommand();
command.CommandText = sql;
List<Tuple<string, string, string>> tuples;
using (var dataReader = command.ExecuteReader())
{
var enumerator = dataReader.GetEnumerator();
tuples = Enumerable.Range(1, int.MaxValue)
.TakeWhile(i => enumerator.MoveNext())
.Select(i => (IDataRecord)enumerator.Current)
.Select(dr => Tuple.Create(dr.GetString(0), dr.GetString(1), dr.GetString(2)))
.ToList();
}
foreach (var tuple in tuples)
{
using (var sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = $"DELETE FROM {tuple.Item1}";
sqlCommand.ExecuteNonQuery();
}
}
}
You might want to configure the relations to propagate changes accordingly ("cascade"), so that when one part of the relation is deleted, the other gets deleted or updated as well.
The DBMS is right in saying that you can not activate a fk relation if the items you are referring to from the other table are missing.

How to create sql connection with c# code behind, access the sql server then conditionally redirect?

This is a question from an experienced beginner!
Using ASP.NET 4 C# AND SQL server,
I have a connection string in web.config to myDatabase named "myCS".
I have a database named myDB.
I have a table named myTable with a primary key named myPK
What are the NECESSARY lines of code behind (minimal code) to create a SQL connection, then select from myTable where myPK=="simpleText"
it will probably include:
sqlconnection conn = new sqlconnection(??? myCS)
string SQLcommand = select * from myDB.myTable where myPK==myTestString;
sqlCommand command = new SqlCommand(SQL,conn);
conn.Open();
booleanFlag = ????
conn.Close();
conn.Dispose();
then
If ( theAnswer != NULL ) // or (if flag)
{
Response.Redirect("Page1.aspx");
}
else
{
Response.Redirect("Page2.aspx");
}
Here is a limited simple tutorial:
First, you want to have a class to do the hard work for you, then you will use it with ease.
First, you have to crate the connection string in your web.config file and name it.
Here it is named DatabaseConnectionString, but you may named it myCS as required in the question.
Now, in App_Code create a new class file and name it SqlComm (this is just an example name) like:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
public class SqlComm
{
// this is a shortcut for your connection string
static string DatabaseConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConStr"].ConnectionString;
// this is for just executing sql command with no value to return
public static void SqlExecute(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
}
// with this you will be able to return a value
public static object SqlReturn(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
object result = (object)cmd.ExecuteScalar();
return result;
}
}
// with this you can retrieve an entire table or part of it
public static DataTable SqlDataTable(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
DataTable TempTable = new DataTable();
TempTable.Load(cmd.ExecuteReader());
return TempTable;
}
}
// sooner or later you will probably use stored procedures.
// you can use this in order to execute a stored procedure with 1 parameter
// it will work for returning a value or just executing with no returns
public static object SqlStoredProcedure1Param(string StoredProcedure, string PrmName1, object Param1)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(StoredProcedure, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(PrmName1, Param1.ToString()));
cmd.Connection.Open();
object obj = new object();
obj = cmd.ExecuteScalar();
return obj;
}
}
}
Okay, this only a class, and now you should know how to use it:
If you wish to execute a command like delete, insert, update etc. use this:
SqlComm.SqlExecute("TRUNCATE TABLE Table1");
but if you need to retrieve a specific value from the database use this:
int myRequiredScalar = 0;
object obj = new object();
obj = SqlComm.SqlReturn("SELECT TOP 1 Col1 FROM Table1");
if (obj != null) myRequiredScalar = (int)obj;
You can retrieve a bunch of rows from the database this way (others like other ways)
This is relevant to your sepecific question
int Col1Value = 0;
DataTable dt = new DataTable();
dt = SqlComm.SqlDataTable("SELECT * FROM myTable WHERE myPK='simpleText'");
if (dt.Rows.Count == 0)
{
// do something if the query return no rows
// you may insert the relevant redirection you asked for
}
else
{
// Get the value of Col1 in the 3rd row (0 is the first row)
Col1Value = (int)dt.Rows[2]["Col1"];
// or just make the other redirection from your question
}
If you need to execute a stored procedure with or without returning a value back this is the way to do that (in this example there are no returning value)
SqlComm.SqlStoredProcedure1Param("TheStoredProcedureName", "TheParameterName", TheParameterValue);
Again, for your specific question return the table using the SqlDataTable , and redirect if dt.Rows.Count >0
Have fun.
There are many ways: LINQ, SqlDataReader, SQLDataAdapter, according to what you want to read (single value, datatable ...), so here is an example:
using (SqlConnection con = new SqlConnection("SomeConnectionString"))
{
var cmd = new SqlCommand("select from myTable where myPK==N'"+ simpleText+ "'",con);
cmd.Connection.Open();
var sqlReader = cmd.ExecuteReader();
while(sqlReader.Read())
{
//Fill some data like : string result = sqlReader("SomeFieldName");
}
sqlReader.Close();
cmd.Connection.Close();
cmd.Dispose();
}

Categories