I am self-learning C# using Visual Studio 2012 and stuck on a connection problem. Basically, I want to use a combobox to connect to a database based on the users selection.
For example: When the user selects TEST1 this will select the test1 database and TEST2 will enable test2 database..etc
The code I have pieced together uses a button which displays the results from a SQL script through a messagebox. At the moment I cant get this to work as the message box does not display anything.
I commented out the MainConnection() as that was a test to see if the connection was working.
Appreciate if someone could point me in the right direction.
Please see the C# code below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace TestDB
{
public partial class Form1 : Form
{
class ComboItemExample
{
public string DisplayString { get; set; }
public string ConnectionString { get; set; }
public override string ToString() { return DisplayString; }
}
private string currentConnection = "Data Source= np-2 ;Initial Catalog= TESTDB Integrated Security=true";
public Form1()
{
InitializeComponent();
var firstConnection = new ComboItemExample { DisplayString = "Data Source= np-2 ;Initial Catalog= TESTDB1 Integrated Security=true" };
comboBox1.Items.Add("TEST1");
var secondConnection = new ComboItemExample { DisplayString = "Data Source= np-2 ;Initial Catalog= TESTDB2 Integrated Security=true" };
comboBox1.Items.Add("TEST2");
}
public void MainConnection()
{
//Make connection to np-2 TESTDB
//string str = "Data Source= np-hums12 ;Initial Catalog= TESTDB;"
//+ "Integrated Security=true";
// ReadOrderData(str);
}
public static void ReadOrderData(string currentConnection)
{
// Run SQL script
string queryString = "SELECT *;";
using (SqlConnection connection = new SqlConnection(currentConnection))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
}
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// call read before accessing data.
while (reader.Read())
{
//display script in message box
MessageBox.Show(reader.GetValue(1).ToString());
}
// close when finished reading.
reader.Close();
}
}
private void CloseUI_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void ShowData_Click(object sender, EventArgs e)
{
MainConnection();
}
private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex <= 0) return;
var newConnection = ((ComboItemExample)comboBox1.Items[comboBox1.SelectedIndex]).ConnectionString;
// use "newConnection" as connection string.
currentConnection = newConnection;
using (var connection = new SqlConnection(currentConnection))
{
}
}
}
}
It looks like you're just adding the text value to your comboboxes, but not actually tying the connection string to it. You may be inadvertently passing the values "TEST1" and "TEST2" as connection strings. You should be adding the new variables you're creating in your constructor as the new items, not those strings. Use the Add() that takes an Item as a parameter.
mycombobox.Add(new Item("Test1", firstConnection));
Assuming your connection strings are correct and functioning, the reason it is displaying nothing is because it is throwing an error with your SQL.
This line is where your mistake lies
string queryString = "SELECT *;";
It is not a valid SQL query, you need to also specify a table. To help in the future, its is often wise to use try-catch statements to help identify potential errors.
For example in your code you could use
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
try
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
MessageBox.Show(reader.GetValue(1).ToString());
}
//dont need to close the reader as the using statement will dispose of it once finished anyway
}
connection.Close();
}
catch (Exception ex)
{
connection.Close();
Console.WriteLine(ex.Message);
//or, depending on the package Debug.WriteLine(ex.Message);
}
}
This will print out the exception and stop your program locking up too. As it stands, your current one won't throw an error saying nothing was found, but it will throw an SQL exception in the output log but won't give you details. Exeception.Message will give you details, or SqlException.Message can provide SQL related messages.
Edit: In response to the comment you posted (and something I missed previously)
Looking at the way you have added your ComboBox items, you haven't even added the objects that you think you have. From your code, your combobox items will be "TEST1" and "TEST2" - not the connection strings.
Instead, you could add your objects to the box like so
comboBox1.Items.Add(new ComboItemExample() {DisplayString ="TEST1",ConnectionString = "Data Source= np-2 ;Initial Catalog= TESTDB1 Integrated Security=true"});
comboBox1.Items.Add(new ComboItemExample() {DisplayString ="TEST2",ConnectionString = "Data Source= np-2 ;Initial Catalog= TESTDB2 Integrated Security=true"});
comboBox1.DisplayMember = "DisplayString";
comboBox1.ValueMember = "ConnectionString";
Then to retrieve the value from the combobox for your query
string myConnectionVal = comboBox1.SelectedValue.ToString();
The reason you are getting the cast error is because you never assigned the ComboItemExample to the combobox in the first place. With the item adding code above you would be able to do this in the future, but if all you need is a single value from the object, ValueMember is easier to use.
Related
Through the information I have found searching here on stackoverflow, I have what I think is 90% of this solved but because of how OleDbConnection is converted to define SqlConnection, the call to the class with the connection and test script wants definition I am unsure how to provide.
I've used these pages to get what I have so far
How to create an SqlConnection in C# to point to UDL file
Calling an SQL Connection method in C#
private static string CONNECTION_NAME = #"C:\Temp\DisplayDB.udl";
public static class MyConnection
{
public static SqlConnection GetSqlConnection()
{
var udlInfo = new OleDbConnection($"File Name={CONNECTION_NAME}");
return CreateSqlConnection(udlInfo);
}
public static SqlConnection CreateSqlConnection(OleDbConnection udlInfo)
{
try
{
string CONNECTION_STRING = $"Database={udlInfo.Database};Server={udlInfo.DataSource};User ID=User;Password=13245;Integrated Security=True;connect timeout = 30";
var connection = new SqlConnection(CONNECTION_STRING);
connection.Open();
return connection;
}
catch
{
Console.WriteLine($"{CONNECTION_NAME} Not found");
return null;
}
}
}
private void DBCheck()
{
// The line below is my issue, mouseover error of ".CreateSqlConnection"
// says there is no argument given that corresponds to the required
// formal parameter 'udlInfo' of
// 'MainWindow.MyConnection.CreateSqlConnection(OleDbConnection)'
using (var con = MyConnection.CreateSqlConnection())
{
con.Open();
var command = new SqlCommand("IF DB_ID ('CodeTest') IS NULL " +
"BEGIN " +
"USE MASTER " +
"CREATE DATABASE CodeTest" +
" END", con);
var reader = command.ExecuteReader();
reader.Close();
con.Close();
}
}
I expect the WPF to use the Database and Server from the UDL file to make the SqlConnection so I can run queries and commands. I understand the security part of UDL in plain text but I do not want hard coded values as this application will be used in various environments nor do I want those values to need definition on each launch of the app.
I want to make my txtSearch textbox in Visual Studio autocomplete.
I have searched around for a long time, for some explanations and tutorials,
but the most are about SQL databases. I have a MS Access database in my application.
I want to make autocomplete suggests from my Titel colon in my database (appData/Film)
First of all, can a textbox do the job, or is a rich textbox necessary to do the job?
I don't expect code from you, but maybe an explanation or a tutorial, you know somewhere?
Thanks. And oops. Important info: My application is based on C#, and coded in Visual Studio.
Try it this way.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Collections;
namespace WinAutoComplete
{
public partial class Form1 : Form
{
AutoCompleteStringCollection ProductList = new
AutoCompleteStringCollection();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//declare connection string
string cnString = #"Data Source=EXCEL-PC\SQLEXPRESS; Initial Catalog=NORTHWND;" +
"Trusted_Connection = True";
/*use following if you use standard security
string cnString = #"Data Source=(local);Initial
Catalog=northwind; Integrated Security=SSPI"; */
//declare Connection, command and other related objects
SqlConnection conGetData = new SqlConnection(cnString);
SqlCommand cmdGetData = new SqlCommand();
SqlDataReader drGetData;
try
{
//open connection
conGetData.Open();
//prepare connection object to get the data through
//reader and populate into dataset
cmdGetData.CommandType = CommandType.Text;
cmdGetData.Connection = conGetData;
cmdGetData.CommandText = "Select ProductName From Products";
//read data from command object
drGetData = cmdGetData.ExecuteReader();
if (drGetData.HasRows == true)
{
while (drGetData.Read())
ProductList.Add(drGetData["ProductName"].ToString());
}
else
MessageBox.Show("No data found in Products tables");
//close reader and connection
drGetData.Close();
conGetData.Close();
//set the default pattern to SuggestAppend
//comboBoxPattern.SelectedIndex = 1;
txtProductID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
txtProductID.AutoCompleteSource = AutoCompleteSource.CustomSource;
txtProductID.AutoCompleteCustomSource = ProductList;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
//check if connection is still open then attempt to close it
if (conGetData.State == ConnectionState.Open)
{
conGetData.Close();
}
}
}
private void comboBoxPattern_SelectedIndexChanged(object sender, EventArgs e)
{
//switch (comboBoxPattern.Text)
//{
// case "Suggest":
// txtProductID.AutoCompleteMode = AutoCompleteMode.Suggest;
// break;
// case "Append":
// txtProductID.AutoCompleteMode = AutoCompleteMode.Append;
// break;
// case "SuggestAppend":
// txtProductID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
// break;
//}
}
}
}
This definitely works, as you can see in the screen shot below.
Also, check this out when you have a chance.
https://www.connectionstrings.com/
I am new to .Net and C# and I have been struggling to get my head round on how to utilise a sql connection created in one section of the code and use it in another. I got 2 buttons on my form. One connects to the database and the other inserts to a table. How do I use the connection variable when inserting to the table?
I hope this makes sense. Thanks
namespace SQL
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
SqlOperations connect = new SqlOperations();
connect.connectToSQL("server=localhost\\SQLExpress;", "database=Cromwell; ");
}
private void btnAddToDatabase_Click(object sender, EventArgs e)
{
SqlOperations addToTable = new SqlOperations();
addToTable.InsertToTable("InputDir", "C:\\");
}
}
public class SqlOperations
{
public bool connectToSQL(string sqlHost, string database)
{
SqlConnection SqlConnect = new SqlConnection("user id=userid;" +
"password=validpassword;" + sqlHost +
"Trusted_Connection=yes;" +
database + "connection timeout=30");
try
{
SqlConnect.Open();
MessageBox.Show("Connected to SQL Express");
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return false;
}
}
public bool InsertToTable(string columnName, string value)
{
SqlCommand myCommand = new SqlCommand();
myCommand.Connection = **SqlConnect**; // THIS BIT COMPLAINS
myCommand.CommandText = "INSERT INTO Config (" + columnName + ") " +
"Values ('" + value + "')";
}
}
}
Solution 1: You can create your connection string as constant string variable and access it using class name from whereever you need it as constant variables are implicitly static(you can access them as global variables)
Try This:
Class MyConnectionString
{
const string strCon="user id=userid;password=validpassword;
server=localhost\\SQLExpress;database=Cromwell;
Trusted_Connection=yes;connection timeout=30";
}
while accessing :
SqlConnection scon=new SqlConnection(MyConnectionString.strCon);
Solution 2:
Create your connection string in Configuration file and access it.
<connectionStrings>
<add name="myConString"
connectionString="user id=userid;password=validpassword;
server=localhost\\SQLExpress;database=Cromwell;
Trusted_Connection=yes;connection timeout=30" />
</connectionStrings>
use it whenever you need it:
string ConnectionString =
ConnfigurationManager.ConnectionStrings["myConString"].ConnectionString;
Check this link, http://www.codeproject.com/Articles/4416/Beginners-guide-to-accessing-SQL-Server-through-C . It is a beginners guide to access SQL Databases using c#.NET.
You can also add the connection string in your web.config, or app.config and then access it from c# code.
C#
// Add a reference at the top of your code file
using System.Configuration;
// Within the code body set your variable
string cs = ConfigurationManager.ConnectionStrings["connectionStringName"].ConnectionString;
VB
' Add a reference at the top of your code file
Imports System.Configuration
' Within the code body set your variable
Dim cs as String = ConfigurationManager.ConnectionStrings("connectionStringName").ConnectionString
Obviously remember to add this (With your own connection string) in your web.config
<connectionStrings>
<add name="ConnStringDb1" connectionString="Data Source=localhost;Initial Catalog=YourDataBaseName;Integrated Security=True;" providerName="System.Data.SqlClient" />
I like that you've defined a class to connect to SQL. You can use that class to manage the lifecycle of your SQL connections, which is a good thing. It would also be good if it handled the connection credentials too so your callers don't have to know what it is. How about this:
public class SqlOperations
{
private SqlConnection Connect()
{
... Get SQL credentials here
... Open and return connection here
}
public bool InsertToTable(string columnName, string value)
{
using (var conn = Connect())
{
using (SqlCommand myCommand = new SqlCommand())
{
myCommand.Connection = conn;
... do your myCommand stuff here
}
}
}
}
Then in your form ditch the connect-to-db button - it's managed for you! All you need is your insert button with this event:
private void btnAddToDatabase_Click(object sender, EventArgs e)
{
SqlOperations addToTable = new SqlOperations();
addToTable.InsertToTable("InputDir", "C:\\");
}
I am changing a console app login over to a web based application and recieve the following error about an Unhandled exception.
In the console app I have the following line of code which resides in the StoredProcDemo class:
StoredProcDemo spd = new StoredProcDemo();
In the Web Application I have:
Login spd = new Login();
I am not sure what to change it over to. Could someone shed some insight thanks and maybe why? Thanks so much.
Here is the full code if needed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data.SqlTypes;
namespace GUI_Login
{
public partial class Login : System.Web.UI.Page
{
SqlConnection conn = null;
SqlParameter parmReturnValue;
Login spd = new Login();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
RunStoredProcParams();
}
public void RunStoredProcParams()
{
//run simple stored procure
spd.RunStoredProcParams();
int Result;
Result = -1;
conn = conn = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=c:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\UserDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True; Integrated Security=SSPI");
conn.Open();
try
{
//create and open a connection object
conn = conn = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=c:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQLEXPRESS\\MSSQL\\DATA\\UserDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True; Integrated Security=SSPI");
conn.Open();
//Create the command object indentifying the stored procedure
SqlCommand cmd = new SqlCommand("PassParamUserID", conn);
//set the command object so it knows to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#FirstName", txtUserName.Text));
parmReturnValue = cmd.Parameters.AddWithValue("#UserId", SqlDbType.Int);
parmReturnValue.Direction = ParameterDirection.ReturnValue;
cmd.ExecuteNonQuery();
Result = Convert.ToInt32(cmd.Parameters["#UserId"].Value);
conn.Close();
// lblResult.Text = Result;
if (Result > 0)
{
lblResult.Text = ("User does exist in database");
}
else if (Result < 0)
{
lblResult.Text = ("Denied, try another user name");
}
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
Even ignoring RunStoredProcParams you'll get a stack overflow as soon as you try to create a new instance:
public partial class Login : System.Web.UI.Page
{
// Removed extraneous stuff...
Login spd = new Login();
}
Why do you want every instance of Login to have a reference to another instance of Login, which it creates immediately?
Basically the constructor is going to be called recursively until it goes bang.
What are you trying to do here, and why? In the console app you may well be creating an instance of StoredProcDemo, but I'm sure it wouldn't be within StoredProcDemo itself (as an instance variable initializer). Perhaps it's in Program or something similar? That would make more sense.
You run RunStoredProcParams() recursively indefinitely.
Comment out this line:
spd.RunStoredProcParams();
Also comment this one:
Login spd = new Login();
in c sharp in win forms i am encountering an error, something like null reference exception
this is my code...and also I don't find any entries in the database table...
public partial class Form1 : Form
{
string strCon, strQry;
SqlConnection con;
SqlCommand cmd;
int rowsaffected;
public Form1()
{
InitializeComponent();
}
box s2 = new box();
class box
{
protected string fname;
protected string lname;
public void name(string s1, string s2)
{
fname = s1;
lname = s2;
}
}
void func(string x, string y)
{
s2.name(x, y);
}
private void btnClick_Click(object sender, EventArgs e)
{
string first = txtFname.Text;
string last = txtLname.Text;
func(first, last);
strQry = "Insert Into Practice Values(" + first + "," + last + " )";
cmd = new SqlCommand(strQry, con);
cmd.Connection.Open();
rowsaffected = cmd.ExecuteNonQuery();
cmd.Connection.Close();
MessageBox.Show(+rowsaffected + " row(s) affected");
}
private void Form1_Load(object sender, EventArgs e)
{
strCon = " Data Source = (local); Initial Catalog = Student; User Id= sa; Password=sa;";
con = new SqlConnection(strCon);
}
alt text http://img682.imageshack.us/img682/6017/hjki.jpg
sorry i didnt mention initialize it u mean to say con = new SqlConnection(strCon); i have done dat in dat case error is {"The name 'xyz' is not permitted in this context. Only constants, expressions, or variables allowed here. Column names are not permitted."}
You are not instantiating the con variable, for example:
SqlConnection con = new SqlConnection(connectionString);
I suppose the error happens because you use con, that is not initialized.
I don't see a SqlConnection con = new SqlConnection(strCon);
I bet your problem is with the connection string, and the connection object is null. Here is a quick way to generate and test a connection string:
Right click the windows desktop or inside a folder in windows explorer,
Click New -> Text Document
Rename the new file to Test.udl (.udl stands for Universal Data Link)
Create and test your connection with the UDL Dialog and click OK
Rename Test.udl to Test.txt and open the text file.
The text file will have a valid connection string that you can use in your code.
Also for your reference, I have simplified your code. The following should be much easier to debug:
private const string dbConnection = "USE THE UDL STRING HERE";
private void btnClick_Click(object sender, EventArgs e)
{
string first = txtFname.Text;
string last = txtLname.Text;
//I think the orig code was missing the single quotes
string query = string.Format("INSERT INTO Practice ('{0}','{1}')", first, last);
int rowsAffected = 0;
//Using statement will automatically close the connection for you
//Using a const for connection string ensures .NET Connection Pooling
using (SqlConnection conn = new SqlConnection(dbConnection))
{
//Creates a command associated with the SqlConnection
SqlCommand cmd = conn.CreateCommand();
//Set your sql statement
cmd.CommandText = query;
//open the connection
cmd.Connection.Open();
//Execute the connection
rowsAffected = cmd.ExecuteNonQuery();
}
MessageBox.Show(rowsAffected + " rows Affected");
}
Are you setting a connection string? It appears you are accessing the Connection object without telling it where to insert the data.
cmd.Connection.ConnectionString = "some string";
I don't think you need cmd.Connection.Open and cmd.Connection.Close.
cmd will open the connection & close it, in order to execute the query/stored procedure.
You are actually creating you connection correctly. What is happening is if you look at your connection string
strCon = " Data Source = (local); Initial Catalog = Student; User Id= sa; Password=sa;";
when it tries to connect it reads this as:
Data Source: " (local)"
Initial Catalog: " Student"
User Id= " sa"
Password - "sa"
So the spaces that you have after the equals signs are getting passed to the SQL server. What your string should look like is this
strCon = "Data Source =(local); Initial Catalog=Student;User Id=sa;Password=sa;"
I am pretty sure that you are never getting an actual connection to your database, but it's failing silently.
Any time you get a null reference on a line that has multiple calls linked together like:
something.somethingElse.somethingElse
break it apart and check each piece. For example, in your case this code:
cmd = new SqlCommand(strQry, con);
SqlConnection sc = cmd.Connection;
System.Diagnostics.Debug.Assert(sc != null, "You got a null connection from the SqlCommand.");
sc.Open();
may demonstrate what the problem is.