I am using C# to write a method that returns the following information about a table:
column names, column types, column sizes, foreign keys.
Can someone point me in the right direction on how to accomplish this ?
This really depends on how you communicate with your database. If you are using LinqToSQL or another similar ORM this would be pretty easy but if you want to get these values via a query I'd suggest you use the INFORMATION_SCHEMA views as these are fast and easy to query.
e.g.
select * from information_schema.columns where table_name = 'mytable'
To get the FK and Schema you should be able to use:
DA.FillSchema()
DS.Table("Name").PrimaryKey
OR calling sp_fkey using the method demonstrated below
Code Snippet from AND Another Link
private void LoanSchema()
{
private List<String> tablesList = new List<String>();
private Dictionary<String, String> columnsDictionary = new Dictionary<String, String>();
string connectionString = "Integrated Security=SSPI;" +
"Persist Security Info = False;Initial Catalog=Northwind;" +
"Data Source = localhost";
SqlConnection connection = new SqlConnection();
connection.ConnectionString = connectionString;
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "exec sp_tables";
command.CommandType = CommandType.Text;
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
tablesList.Add(reader["TABLE_NAME"].ToString());
}
reader.Close();
command.CommandText = "exec sp_columns #table_name = '" +
tablesList[0] + "'";
command.CommandType = CommandType.Text;
reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
columnsDictionary.Add(reader["COLUMN_NAME"].ToString(), reader["TYPE_NAME"].ToString());
}
}
You can use the SqlDataAdapter.FillSchema() method.
Alternatively you can use the SqlDataAdapter.Fill() method after setting the MissingSchemaAction property of the SqlDataAdapter to AddWithKey. But if you only want the schema you must ensure that your query returns no rows. This can be accomplished by adding a statement like WHERE 1=2 to your query.
If you are using MS SQL Server then You should definately have a look at SMO namespace (server management objects).
There are objects which You can use in .net responsible for all kinds of things in a database (including but not limited to tables, columns, constraints etc.)
I think you need the System.Data.DataTable class:
http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx
Related
I created a database in Microsoft Access 2007 with the stock products of a company using an application buit in C # . I have a form to search for products by reference in the database but I am not able to obtain query results. The problem is that the column with the reference product has various spaces in the reference name:
Column product reference in the database
This is the code that I have to perform this query:
private void Ref_btn_Click(object sender, EventArgs e)
{
string connStr = (#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Stock.accdb");
string query = "Select * from product where product_ref like '%' + textBox_ref.Text + '%'";
using (OleDbConnection conn = new OleDbConnection(connStr))
{
using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn))
{
DataSet ds = new DataSet();
adapter.Fill(ds);
dataGrid_stock.DataSource = ds.Tables[0];
}
}
}
What I want is to introduce for example in the textbox: "VDS" or "NT" and the query return "VDS 15P M X" and "NIP FIN NT LL" respectively.
thanks in advance,
Your query looks fine to me, I would only add a .Trim() to the end of textBox_ref.Text to prevent spaces from appearing between the search term and the % sign.
Your query has "wrong" quotes. Try this:
string query = "Select * from product where product_ref like '%" + textBox_ref.Text + "%'";
Here's a proper way to execute SQL statement safely:
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Stock.accdb";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(
"SELECT * FROM product WHERE product_ref LIKE '%#value%'", connection))
{
command.Parameters.Add(new SqlParameter("value", textBox_ref.Text.Trim()));
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// Do whatever you want to do with the queried data
}
}
}
This snippet is ideal for preventing SQL injections. It uses so called parameterized queries to avoid security issues. Futhermore, it manages to close your database connection after the code is executed by itself.
string.Trim() erases leading or heading whitespaces. This prevents unexpected mistakes.
I was wondering if it is possible for the update button to save the changes made in the table. I wrote this code but I have no idea how it could possibly work
This is the code i wrote for the update button:
string conString = "Data Source=MIRANDA-PC;Initial Catalog=Futebol do Rosa;Integrated Security=True";
SqlConnection con = new SqlConnection(conString);
string selectSql = "Update Players$ set Player Name='" + dataGridView2.Text + "";
SqlCommand cmd = new SqlCommand(selectSql, con);
con.Open();
This is the table I want to update the values in:
Well, you just need to execute your query with ExecuteNonQuery.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your SqlConnection and SqlCommand.
And if your table or column names more than one word, you need to use them with [] as [Player Name]. And honestly, it is a little bit weird to use $ sign in a table name.
using(SqlConnection con = new SqlConnection(conString))
using(SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "Update Players$ set [Player Name] = #name";
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
}
You have to execute your SQL query with your db object.
dbinstance.ExecuteSqlCommand(string sqlcommand, object[] params);
This method is both for DDL and DML.
you can also use ExecuteNonQuery method.
cmd.CommandText = "Update Players$ set [Player Name] = #Playername";
cmd.Parameters.Add("#Playername", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
The best solution (if possible) to to convert your DAL (Data Access Layer) to Entity-framework based, instead of writing your own SQL queries. This is safe-by-design and never is vulnerable to SQL Injection of any kind.
Here is some mockup code:
using (AppEntities currDb = new AppEntities)
{
Players PlayerToEdit =
from player in currDb.Players
where player.PlayerID == lngPlayerID
select player.First();
PlayerToEdit.PlayerName = dataGridView2.Text;
currDb.SaveChanges();
}
You can read about it some more here:
https://msdn.microsoft.com/en-us/data/ef.aspx
C# visual studio 2012 professional asp.net
I have a table containing usernames: Josh, Jeremy, Jared, Justin...
And I created a web page gridview that shows the entire table but I only want it to show Justin and nothing else.
How do I do this?
Here's some code that didn't work:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
SqlDataReader rs;
con.Open();
SqlParameter uName = new SqlParameter("paramFName", Account.Text);
cmd.Parameters.Add(uName);
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
rs = cmd.ExecuteReader();
cmd.Parameters.Clear();
rs.Close();
Am I supposed to create a view of the table? I tried but wasn't successful.
tips?
You simply missed the "#" at the parameter name:
SqlParameter uName = new SqlParameter("#paramFName", Account.Text);
In case of your where-clause this has the effect that you didn't provide anything for the specified parameter which simply let the query provider ignore this condition, which results in the effective query SELECT * FROM Transactions.
Beside you should think about using the using block:
using (SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"))
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
cmd.Parameters.AddWithValue("#paramFName", Account.Text);
con.Open();
using (var rs = cmd.ExecuteReader())
{
//ToDo: Do something with the reader.
}
}
And another hint: If you need to fill up a DataTable with the result, you can use a SqlDataAdapter instead of using the data reader:
using (var adapter = new SqlDataAdapter(cmd))
{
var dataTable = new DataTable();
dataTable.TableName = "QueryResult";
adapter.Fill(dataTable);
return dataTable;
}
If you are trying to select the first 10 names for example then you need to change your SQL Select to the following:
cmd.CommandText = "SELECT TOP 10 * FROM Transactions WHERE FName=#paramFName";
Is that what you were after?
EDIT
OK so you are not actually displaying your data anywhere which is the actual problem.
You need to create a datatable and display it in a gridview.
Check out the following links for examples:
Gridview examples
MSDN Gridview examples
Your code seems fine, although you do not provide much information.
If you're using SQL Server 2012 have a look at the keywords OFFSET and FETCH.
For earlier versions you need to use ROW_NUMBER OVER PARTITION
As a good practice you should always limit the number of elements returned.
Ok either I'm really tired or really thick at the moment, but I can't seem to find the answer for this
I'm using ASP.NET and I want to find the amount of rows in my table.
I know this is the SQL code: select count(*) from topics, but how the HECK do I get that to display as a number?
All I want to do is run that code and if it = 0 display one thing but if it's more than 0 display something else. Help please?
This is what I have so far
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
SqlConnection con = new SqlConnection(connectionString);
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
if (topiccmd == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
but I know I'm missing something seriously wrong. I've been searching for ages but can't find anything.
PHP is so much easier. :)
Note that you must open the connection and execute the command before you can access the result of the SQL query. ExecuteScalar returns a single result value (different methods must be used if your query will return an multiple columns and / or multiple rows).
Notice the use of the using construct, which will safely close and dispose of the connection.
string selectTopics = "select count(*) from topics";
// Define the ADO.NET Objects
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand topiccmd = new SqlCommand(selectTopics, con);
con.Open();
int numrows = (int)topiccmd.ExecuteScalar();
if (numrows == 0)
{
noTopics.Visible = true;
topics.Visible = false;
}
}
ExecuteScalar is what you're looking for. (method of SqlCommand)
Btw, stick with C#, there's no way PHP is easier. It's just familiar.
You need to open the connection
This might work :
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "select count(*) from topics";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
// Data is accessible through the DataReader object here.
sqlConnection1.Close();
Similar Question: C# 'select count' sql command incorrectly returns zero rows from sql server
What's the safest way of generating SQL queries in C#, including cleansing user input so it's safe from injection? I'm looking to use a simple solution that doesn't need external libraries.
Use Sql Parameters:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter(v=vs.80).aspx
Here's an example in C#
SqlCommand tCommand = new SqlCommand();
tCommand.Connection = new SqlConnection("YourConnectionString");
tCommand.CommandText = "UPDATE players SET name = #name, score = #score, active = #active WHERE jerseyNum = #jerseyNum";
tCommand.Parameters.Add(new SqlParameter("#name", System.Data.SqlDbType.VarChar).Value = "Smith, Steve");
tCommand.Parameters.Add(new SqlParameter("#score", System.Data.SqlDbType.Int).Value = "42");
tCommand.Parameters.Add(new SqlParameter("#active", System.Data.SqlDbType.Bit).Value = true);
tCommand.Parameters.Add(new SqlParameter("#jerseyNum", System.Data.SqlDbType.Int).Value = "99");
tCommand.ExecuteNonQuery();
In essence don't do this
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = '" + TextBox1.Text + "'"
...
do
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = #MyValue";
command.Parameters.AddWithValue("MyValue",TextBox1.Text);
...
Basically never build your sql command directly from user input.
If you use an ORM, such as EntityFrameworks / POCO all queries are done in the latter form.
The first rule of thumb is to make sure you use parameterized queries/commands. Basically don't dynamically build a sql string that includes something that the user has input into the page.
If you use on ORM (EF, L2S, Nhib), this is typically handled in most cases because most all of them run parameterized queries.
Parametrize your queries.
In case if you build some TSQL which builds some other dynamic TSQL - then use some described technique
What does "parametrizing means?
See, not use something like this:
sqlCommand.CommandText = "select * from mytable where id = "+someVariable;
use this:
sqlCommand.CommandText = "select * from mytable where id = #id";
sqlCommand.Parameters.AddWithValue("#id", someVariable);
Make use of Parametrized Queries.
Simple Example.
var sql = "SELECT * FROM MyTable WHERE MyColumn = #Param1";
using (var connection = new SqlConnection("..."))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#Param1", param1Value);
return command.ExecuteReader();
}
More Detailed Example.
protected void btnGoodAddShipper_Click(object sender, EventArgs e)
{
string connStr = c
"Server=(local);Database=Northwind;Integrated Security=SSPI";
// this is good because all input becomes a
// parameter and not part of the SQL statement
string cmdStr =
"insert into Shippers (CompanyName, Phone) values (" +
"#CompanyName, #Phone)";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
// add parameters
cmd.Parameters.AddWithValue
("#CompanyName", txtCompanyName.Text);
cmd.Parameters.AddWithValue("#Phone", txtPhone.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
Using DBML and LINQ to handle it for you. Many people have worked on those to ensure those issues are well mitigated.
And if not than at least parametrize your queries.
A proper name for DBML is linq2sql or an advanced version is called entity framework. These technologies are provided by Microsoft and well integrated with visual studio. Does not require additional libraries.
Pretty stable products..