It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
this is my snippet , please help me why the con .open is not working inside the function tabledel
i want to delete the table once i press the button , the connection gets opened for the first time but couldnt open it for the second time inside the function tabledel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
namespace WFA_CREATE_DELETE
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
OleDbConnection con = new OleDbConnection(#"PROVIDER=Microsoft.ACE.OLEDB.12.0; Data Source=C:/Users/Dinesh/Documents/Database3.accdb");
OleDbDataAdapter ea = new OleDbDataAdapter();
DataSet dsl;
DataSet esl;
private void Form1_Load(object sender, EventArgs e)
{
OleDbDataAdapter da = new OleDbDataAdapter();
dsl = new DataSet();
con.Open();
DataTable table2 = con.GetSchema("tables");
MessageBox.Show("Database Open");
dataGridView1.DataSource = table2;
con.Close();
con.Dispose();
}
public void Tabledel()
{
int a = 0, d = 0, count, itr;
count = dataGridView1.RowCount;
itr = dataGridView1.ColumnCount;
while (a < count)
{
for (d = 0; d < itr; d++)
{
if (dataGridView1.Rows[a].Cells[d].Value.ToString() == textBox1.Text)
{
MessageBox.Show("table exists");
esl = new DataSet();
string vsql = "drop table '" + textBox1.Text + "'";
ea = new System.Data.OleDb.OleDbDataAdapter(vsql, con);
OleDbCommand cmdea = new OleDbCommand(vsql, con);
//cmdea.Connection = con;
con.Open();
cmdea.ExecuteNonQuery();
MessageBox.Show("table dropped");
con.Close();
con.Dispose();
}
}
a++;
}
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
public void button1_Click(object sender, EventArgs e)
{
Tabledel();
}
}
}
link
As I see you get this error:
The ConnectionString property has not been initialized.
May be you will create (dispose) your connection in somewhere else (except in form class global variable), so I suggest to set connection string explicitly (With recreating connection):
con = new OleDbConnection(
#"PROVIDER=Microsoft.ACE.OLEDB.12.0; Data Source=C:/Users/Dinesh/Documents/Database3.accdb");
con.Open();
Anyway it wasn't hard to include main part of your code here in SO.
The connection object is created when your Form is created. You open, use, close and DISPOSE the connection object in the Form_Load method. Therefore the connection object is gone by the time your button click handler starts to execute.
You have to either create a new connection object in the button click handler, or NOT dispose it in the Form_Load method.
Really hard to decode what your actual problem is, what's causing it and so on, but there are many problems with your code.
First off you shouldn't initialize your con object the way you do. Every time you are done using it and call Dispose, you'll destroy it. In any case it isn't rebuilt until next time your Form1 class is initialized. That's probably why you're getting the errors.
A suggestion would be to have a singleton that handles your connection. This leads me to the next point: It's a very bad idea to open new connections inside a loop. If you've made your connection handeler properly, you'd only have to open one connection per call. I'll give you so much better performance, which you'll notice if you have many elements to iterate through.
Next up, your delete statement is subject to SQL injections. You should strongly considder using a way that minimizes the user input to selecting from a list so they can't type in weird queries in your textBox1.Text
That's just some of it.. I hope you can use it.
Oh and please, please write a better question. Don't just say "Uh, something doesn't work. Link". Condensate your code and think about what you're asking to make sure it'll be widely understood.
Related
UPDATE:
This great answer from Steve https://stackoverflow.com/a/57692761/5758150
plus needing to include: Integrated Security=SSPI in my connection string has resolved this issue.
Many thanks to all for their assistance.
I am a C# newb and this is my first project.
The code is designed to query a sql server table and return the results into a datagridviewer on a windows Form.
The form compiles with no errors but simply shows a blank datagridviewer.
Can anyone advise what I am doing wrong please?
I have checked the server name db name etc and they are all correct.
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data;
using System;
using System.Data.SqlClient; //For SQL Connection
namespace Reference_Table_Updater
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void GetList()
{
String strConnection = "server;" +
"Database='Scratchpad';";
SqlConnection con = new SqlConnection(strConnection);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = con;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "Select * from dbo.UPDATE_Test";
SqlDataAdapter sqlDataAdap = new SqlDataAdapter(sqlCmd);
DataTable dtRecord = new DataTable();
sqlDataAdap.Fill(dtRecord);
dataGridView1.DataSource = dtRecord;
}
private void Form1_Load()
{
GetList();
}
}
}
That Form_Load is not correct. Probably you have added it manually and it is never called. Of course the grid is not filled.
To have your Form_Load called you need to bind it to the Load event
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += Form_Load;
}
private void Form_Load(object sender, EventArgs e)
{
GetList();
}
Of course, this binding of event handlers to events is usually done using the Form Designer, double clicking on the event that you want to handle. (and thus is not required to write the binding in your form constructor)
Now, your GetList should be called and if there are errors there they should be raised with an exception. The GetList code seems to be correct, unless there is a problem with the connectionstring or the database table.
Here you need to use user and password
String strConnection = "server;" + "Database='Scratchpad';"; Like this example:
"SERVER=localhost; user id=root; password=; database=Scratchpad"; Or are you using windows autentication?
I would like to ask if it is possible to load a database into an array or list, and then run queries on it? I have the following code.
string cs = "Data Source=dataBase.sqlite;Version=3;";
SQLiteConnection con;
SQLiteDataAdapter adapt;
DataTable dt;
private void textBox1_TextChanged(object sender, EventArgs e)
{
con = new SQLiteConnection(cs);
con.Open();
adapt = new SQLiteDataAdapter("select * from Table1 where CnName1 like '" + textBox1.Text + "%'", con);
dt = new DataTable();
adapt.Fill(dt);
dataGridView1.DataSource = dt;
con.Close();
}
This works, but it creates a new dataTable whenever a query is run, the problem code is:
dt = new DataTable();
The program is meant to be constantly running, so this is inefficient, since it will eat up a lot of memory. How do I load the database into an object, and then run queries on that object? The table is only meant to have 1 column, and the queries run will only serve as a search function. I want to load the database only once, that is when the program is started, then the connection will be closed, and everything else will be done with the program, not with the database.
Edit: I would like to state for anyone else viewing this question to also view saab669's answer, as it provides useful information as well, however I can not choose two answers.
Assuming you have a form containing your text box. Declare a class level variable to store you datatable.
private DataTable _data;
Create a class to encapsulate your database connection and retrieval of data.
public class MyDataBaseConnection
{
public DataTable ReturnMyData(string valueFromTextBox)
{
var cs = "Data Source=dataBase.sqlite;Version=3;";
SQLiteConnection con;
SQLiteDataAdapter adapt;
DataTable dt;
try
{
con = new SQLiteConnection(cs);
con.Open();
adapt = new SQLiteDataAdapter("select * from Table1 where CnName1 like '" + textBox1.Text + "%'", con);
dt = new DataTable();
adapt.Fill(dt);
con.Close();
return dt;
}
catch (Exception ex)
{
//Log here.
throw;
}
finally
{
con = null;
adapt = null;
//Or Dispose. I dont have SQL lite so dont know if they implement IDispose
}
}
}
In your textbox change event, call the db code and assign to your class level var
private void textBox1_TextChanged(object sender, EventArgs e)
{
var myDBConnection = new MyDataBaseConnection();
_data = myDBConnection.ReturnMyData(textBox1.Text);
dataGridView1.DataSource = null;
dataGridView1.DataSource = _data;
}
When the text changed event fires again, the data will be changed in the grid.
Hope that helps.
My response is too long for a comment, but I want to reply to a few things you said:
but it creates a new dataTable whenever a query is run, the problem code is dt = new DataTable(); The program is meant to be constantly running, so this is inefficient, since it will eat up a lot of memory.
Sort of. You only ever have one DataTable object. It's just that every time that event fires, it's re-querying the database. So you're not consuming an excessive amount of memory (unless your DB is huge!), or at least not in the way you think you are.
How do I load the database into an object, and then run queries on that object?
As I mentioned in my comment, you're doing that already. Just in a less-than-ideal event handler. Depending on how you want the application to behave, you should move this to the form load event as defined here. Or perhaps it might make more sense to have a button with a click event. The form load could add a long delay to your application's start up and the user might think it froze, depending on how long it takes you to fetch all the records from the DB.
Also, from the code snippet you provide, am I correct in assuming you define DataTable dt; outside of the event handler, on the class level?
Anyways, per the MSDN article I linked in my comment, once you have a DataTable populated then you can simply do things like this:
DataRow[] foundRows;
foundRows = dataSet1.Tables["TableName"].Select("ColumnName LIKE 'your_search_value%'");
Lastly, and I cannot stress this enough about the code you provided: DO NOT concatenate strings for a query which will execute against a database. I don't care if it's for a homework assignment or a little tool only you will use, there's no excuse for not taking the extra time to learn how to do it the right way. There's no reason to build a bad habbit, as this is susceptible to SQL injection which is comically easy to protect against. You absolutely should spend the 30 minutes to learn about parameterized queries.
Hello I have read several articles but am not getting the answer I seek. I wish to do a two fold process. 1. Populate a datagridview from a query NOT a table directly with a button that executes a query to populate. 2. Change the values on the datagrid to speak BACK to the database to make the changes. The problem I am encountering is example I find assume you are having a STATIC universe NOT one that may change. I already knew the population portion but I am curious how you use the datagridview to make a connection to a database and say: "Do what I show at this point in time as changes and save them to the database they originally came from."
Code I was following slightly:
http://www.switchonthecode.com/tutorials/csharp-tutorial-binding-a-datagridview-to-a-database They used an Access method and I am using SQL but it should not matter much.
EG: I can set a dataAdapter element in one process instance but the other instance is NOT aware of it. I assume something can be done as you can do these quite easily with drag and drop with datasets. Maybe I am going about it wrong as well and should be setting some elements static and some dynamic. All I really want is to prove I could change the values under VALUE to something different and commit that back to the database with a binding source. However the binding source is unknown in another instance and setting some things up statically have met with failure they way I defined them. Any help is much appreciated, thanks!
PRE SET UP:
Create a 'Test' Database with a single table defined as:
Create table Test ( ID int Identity, VALUE varchar(2) )
insert into Test values ('A'),('B'),('C')
Create a Windows Form Application in Visual Studio 2010(should work in 2008 or earlier as I don't believe I am doing anything explicitly .NET 4.0). Windows Form should have two buttons: a. 'btnPopulate' b. 'btnUpdate'; a Text Box: 'txtquery' filled with text: 'select * from Test'; and a datagridview: 'gridview'.
Actual code used behind form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace DataGridTestDBUpdater
{
public partial class TestDataGrid : Form
{
public string con = "Integrated Security=SSPI;Persist Security Info=False;Data Source =(local);Initial Catalog=Test";
public TestDataGrid()
{
InitializeComponent();
}
private void btnPopulate_Click(object sender, EventArgs e)
{
string query = txtquery.Text;
using (SqlConnection cn = new SqlConnection(con))
{
using (SqlCommand cmd = new SqlCommand(query, cn))
{
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
using (DataTable table = new DataTable())
{
cn.Open();
using (BindingSource bs = new BindingSource())
{
adapter.SelectCommand = cmd;
adapter.Fill(table);
bs.DataSource = table;
gridview.DataSource = bs.DataSource;
}
cn.Close();
}
}
}
}
}
private void btnUpdate_Click(object sender, EventArgs e)
{
using (BindingSource bs = new BindingSource())
{
bs.DataSource = gridview.DataSource;
using (DataTable table = new DataTable())
{
using(SqlDataAdapter adpt = new SqlDataAdapter())
{
bs.DataSource = gridview.DataSource;
/// ALL OF MY WORK IS FAILING FROM HERE ON ///
/// WANT TO GET UPDATE TO WORK HERE: ///
///
///adpt.Update(bs.DataSource);
}
}
}
}
}
}
I may have misunderstood your question. Feel free to correct, if that is the case. From what I gather, you want a very persistent connection for your application to your database. That is, if something is changed in one instance of your application the other instance should automatically be aware of the change and refresh its presentation of the underlying data.
If my understanding of your question is correct, unfortunately, there is no straight forward solution to it. What you show in your grid in one instance of your application is an IN MEMORY representation of (in your case a DataTable object) the underlying data that was populated with the database values AT THE TIME of invoking "btnPopulate_Click" method. Any changes in database after that is NOT transparent to your instance until the underlying datatable is refreshed again.
I figured it out, you just have to set private instances of the SqldataAdapter and BindingSource. Then one instance will know about the other. Plus, I should NOT have been using the (using) reference. In most cases it is a wise choice as it implements a dispose method but in this instance I need another method to see the instance I declared in population. Answer I did(This WILL NOT WORK with multiple tables or tables where you do not define a primary key).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace TestEntryForm
{
public partial class Form1 : Form
{
private BindingSource bs = new BindingSource();
private SqlDataAdapter da = new SqlDataAdapter();
private string cnc = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Test;Data Source=localhost";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
datadridview.DataSource = bs;
}
private void SelectCommand(string selectcmd)
{
da = new SqlDataAdapter(selectcmd, cnc);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(da);
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
da.Fill(table);
bs.DataSource = table;
datadridview.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
}
private void btnLoad_Click(object sender, EventArgs e)
{
SelectCommand(txtQuery.Text);
}
private void btnUpdate_Click(object sender, EventArgs e)
{
da.Update((DataTable)bs.DataSource);
}
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I try to make an app which manages client's contacts. The form is very very simple. There are: panel (inside this panel are labels with names, emails, etc.) and a listbox which shows all saved contacts in sdf file. I have one big problem. I want to refresh the listbox content via a method in another class. I set the listbox as public, debugger shows no errors during the project build. When the form loads, this message is prompted (via try-catch exception): "Object reference not set to an instance of an object.". I tried to do this project differently - everything was written in one class. Here's the code:
database.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlServerCe;
namespace Contacts
{
class Database
{
public static void RefreshListBox()
{
SqlCeConnection connection = null;
try
{
var form1 = Form.ActiveForm as Form1;
connection = new SqlCeConnection("Datasource = C:\\Kontakty.sdf");
connection.Open();
SqlCeCommand command = new SqlCeCommand("SELECT * FROM Contacts", connection);
SqlCeDataReader reader = command.ExecuteReader();
while (reader.Read())
{
form1.listBox1.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Contacts
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox();
}
}
}
Does anyone here know what is wrong?
PS: kontakty = contacts (in Czech ;-))
This might help:
public static void RefreshListBox(ListBox listBox)
...
while (reader.Read())
{
listBox.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
And then:
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox(this.listBox1);
}
Other than that, you really shouldn't be passing forms or listboxes into database classes. It should be the other way around-- your form should just get the data from the class and populate the listbox there.
Form.ActiveForm is probably null because From1 is still being loaded and probably not yet visible and hence not active.
The first thing I would do is to pass a reference to your listbox to the RefreshListBox() function.
There is no reason for your class to have any knowledge or reference to Form1.
try this in your form:
private void Form1_Load(object sender, EventArgs e)
{
Database.RefreshListBox(this.listBox1);
}
And this in your class:
public static void RefreshListBox(ListBox listbox)
{
SqlCeConnection connection = null;
try
{
listbox.Items.Clear() //I assume you may want to refresh?
connection = new SqlCeConnection("Datasource = "C:\\Kontakty.sdf");
connection.Open();
SqlCeCommand command = new SqlCeCommand("SELECT * FROM Contacts", connection);
SqlCeDataReader reader = command.ExecuteReader();
while (reader.Read())
{
listbox.Items.Add(reader.GetString(0) + " " + reader.GetString(1));
}
}
catch(Exception exc)
{
MessageBox.Show(exc.Message);
}
}
I've left out a lot (like persisting the selected item(s)), but you get the idea.
Also - don't use field index for your SQL return values if you don't specify their order. Call the fields by name (I know you can't with the CE SqlDataReader) or better yet: specify them (and their order) in your SQL statement. You never know when a DB will get moved or regenerated and the default order from "Select * From ..." will be munged, plus if fields get added in later versions, you're only wasting bandwidth/data space to return their values if you're not going to use them.
I am working on a Cook Book using a database. I have been working with tutorials to build my project since I'm still just a novice.
I have asked before how to search a database using a button, and the help was so quick, I'll have to ask another question.
Here's the problem:
My form allows a user to find recipes that have a certain ingredient. It allows them to type an ingredient in the textbox, and the button shows all the results (the recipes' names) in a listbox. That part has been successfully coded, thanks to the help here. Once the list box is populated, though, I'd like the user to be able to select a recipe from the list box, and the textboxes next to the listbox fill with the particular recipe's data information (such as ingredients, directions, and additional comments).
What recipes populate the listbox are up to the user, so I can't really code this without some serious logic, right?
Here is the code for my entire form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Collections;
namespace Cookbook
{
public partial class BrowseIngredients : Form
{
public BrowseIngredients()
{
InitializeComponent();
}
SqlConnection con;
SqlDataAdapter dataAdapt;
DataSet dataRecipe;
int MaxRows = 0;
int inc = 0;
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Exit Cook Book?", "Exit?", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
Application.Exit();
}
}
private void btnBack_Click(object sender, EventArgs e)
{
BrowseRecipes goBack = new BrowseRecipes();
Close();
goBack.Show();
}
private void howToSearchToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("To look for recipes with ingredients you have, simply type in the first ingredient you have to cook. \r\n To narrow your search, add another ingredient you'd like to search for in the recipe results.", "Search by Ingredients");
}
private void BrowseIngredients_Load(object sender, EventArgs e)
{
con = new SqlConnection();
con.ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Documents and Settings\\Cady Wong\\My Documents\\Visual Studio 2010\\Projects\\Cookbook\\Cookbook\\Recipes.mdf;Integrated Security=True;User Instance=True";
dataRecipe = new DataSet();
con.Open();
string sql = "SELECT* From CookBookRecipes";
dataAdapt = new SqlDataAdapter(sql, con);
dataAdapt.Fill(dataRecipe, "CookBookRecipes");
NavigateRecords();
MaxRows = dataRecipe.Tables["CookBookRecipes"].Rows.Count;
con.Close();
}
private void NavigateRecords()
{
DataRow dRow = dataRecipe.Tables["CookBookRecipes"].Rows[inc];
}
//This is the search and populate listbox code //
private void btnSearch_Click(object sender, EventArgs e)
{
if (tbSearch.TextLength >= 1)
{
//MessageBox.Show("This will work when you put in a word!");
listBox1.Items.Clear();
string searchOut = tbSearch.Text;
int result = 0;
DataRow[] returnRows;
returnRows = dataRecipe.Tables["CookBookRecipes"].Select("Recipe_Ingredients LIKE '*" + searchOut + "*'");
result = returnRows.Length;
//This allows mutiple results to be seen one line after another //
if (result > 0)
{
string temp ="";
DataRow rowBack;
for (int index = 0; index < returnRows.Count(); index++ )
{
rowBack = returnRows[index];
listBox1.Items.Add(rowBack[0].ToString());
temp += rowBack[0].ToString();
temp += "\n";
}
}
else
{
MessageBox.Show("No record");
}
}
else
{
MessageBox.Show("Please enter an ingredient to search for!", "Search");
}
}
}
}
If you need more information, just let me know!
Thank you in advance!
Ok, I haven't really provided the answer- more bane you with a few tips that hopefully will push you forward, not just on this project, but as a programmer in general.
On a slight side note before I continue, the tags "multiple" and "logic" are a perculiar choice for your question
Regarding BrowseIngredients_Load:
Here you use a SqlConnection which implements the IDisposable interface. The best practice (and it's very highly recommended) is to always use the Using Block Pattern when working with objects that implement IDispoable (at least where possible).
using (con = New SqlConnection(connectionString)){
' use the connection within these bracers
}
' because you used this pattern, the object is disposed correctly, memory deallocated, etc
The next bit of advice would be to take a look at Linq to SQL (L2S for short). L2S is an Object-Relational Mapper. Sounds complicated but basically means it is responsible for mapping your database objects (Tables, Views, etc) to your Domain Model (Classes, Strucutres, etc). Probably again sounds a bit complicated, but trust me, check out these dead simple tutorials and you'll love it:
CodeProject Article including Source Code
Part 1 of Scott Gu's Blog/Tutorials
Good ol' MSDN Introduction to L2S
NB: There are many ORMs available, Microsoft itself also provides Entity Framework, but L2S should be easy to learn and arm you with enough knowledge to make educated choices towards ORM alternatives in the future
If you go with L2S (which once you've spent a couple hours with, you'll find you'll use over writing out T-SQL in your code every time) it solves a couple other issues, such as introducing SQL Injection which Linq would handle for you.
It would also solve your overall problem, or almost. With Linq to SQL, displaying the Recipes data would be simple because they would just be the properties of a class.
txtIngredients.Text = myAutoGeneratedLinqRecipe.Ingredients;
I hope that helps get you on your way, I'm sure somebody else will give you the code to complete your exercise without introducing new code patterns and technologies ^^
EDIT: A quick exmaple of the using block so you get the idea:
Private void BrowseIngredients_Load(object sender, EventArgs e)
{
string connStr = "Data Source=.....etc";
using (con = New SqlConnection(connStr))
{
con.Open
' get your data here - if you were losing Linq, you wouldnt have to worry
' about connections or Sql at all ;-)
con.Close
} ' this ensures that the connection is disposed correctly, even if for example
' you throw an exception inside the block which isn't caught
}