![]() |
Database »
Database »
General
Intermediate
Web SQL UtilityBy Ashley van GervenA simple ASP.NET application to run queries against your databases. Stores history and favourites. |
Javascript, C# 1.0, Windows, .NET 1.1, ASP.NET, VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This little ASP.NET utility lets you run SQL queries against databases accessible to the web server. Initially, this started as a script to run queries against an Access database, without having to download it. Every now and then, you might need to do maintenance chores, or retrieve some raw data to check something. This utility facilitates that by allowing queries to be saved as a favourite, as well as keeping the history of previous queries.
INSERT queries
DataSet XML
This utility is not meant to replace database admin tools like phpMyAdmin. Rather, it was built to be simple and light-weight, allowing it to be integrated into other web applications. It's meant to provide quick and easy access to your data, and allow you to test queries, as well as modify your databases. You can configure multiple connections (not necessarily of the same database type), which gives you a common interface regardless of which database you need to query. The history and favourites-list remembers which database a query was executed against, and will select the appropriate radio button when you click on a query in those lists.
It also generates schema details for OLEDB, SQL Server, and MySQL connections. In the schema popup, you can click on the column names or table name headings to insert the name into the query textbox (replacing the current selection). The schema popup does not reload when you click the Schema link if that schema is already open in the popup. The popup will merely get focused to the forefront.

The Execute button, in addition to the obvious, adds the query to the history, and if the "Add to favourites" checkbox is checked, adds the query to the favourites. The shortcut key for this button is Alt-E. Multiple queries can be submitted simultaneously - separated by GO statements or ";;;" (customizable). Multiple result grids will be displayed. Note: the user-account that aspnet_wp runs as will need Modify permission on the configured paths for favourites and history (normally, ASPNET or INTERACTIVE_NETWORK).
The INSERTs button will generate INSERT SQL queries that you can execute against another database (e.g., for backing up a single table). If you use this feature with SQL Server, note that you should specify that you are overriding IDENTITY values, by running the following queries before and after the INSERT queries:
SET IDENTITY_INSERT table_name ON
--- INSERT QUERIES ---
SET IDENTITY_INSERT table_name OFF
The DataSet XML button will let you download the DataSet XML for your SELECT queries. Multiple result sets are supported. The tables are named Table1, Table2, Table3 etc., for each result set.
The CSV button will let you download a single CSV, with each result set underneath the other.
The HTML encode results checkbox escapes any HTML characters in your result set.
The Wrap query textbox checkbox changes the text-wrapping on the query textbox (i.e., horizontal scrollbar on/off for long lines). This was a major headache to implement for Firefox (v1.5) - which required coming up with a complete workaround since setting the wrap attribute on the TEXTAREA element just didn't have any effect. I assume this is a bug in Firefox, and is the first time I feel let down by this impressive browser. (More details on the workaround below.)
Initially, the SQL page shows the Favourites "tab" selected. But once a query is executed, the History "tab" becomes selected by default. They're not really tabs, visually, but the bold text shows which list is selected. The History list has a "Complete History" link underneath which will be shown queries executed for previous sessions in a popup. This is useful to keep a record of queries run by yourself or anybody else. If you suddenly have 1000 rows missing from your database, you can investigate the query history for the potential cause. The popup has delete links to clear a particular history session, or all of them.
There is a custom configuration section that lets you customise this utility. Here is an example:
<DbUtilConfig>
<Connections>
<Connection name="Access" type="oledb" cs="" csAppKey="AccessDb" />
<Connection name="SQL Server" type="mssql" cs=""
csConfKey="SqlServerConnStringIAM" />
<Connection name="MySQL" type="odbc"
cs="DRIVER={MySQL ODBC 3.51 Driver}; SERVER=localhost;
USER=test; PASSWORD=test; DATABASE=test" />
</Connections>
<FavouritesFile>data/SqlFavourites.xml</FavouritesFile>
<HistoryFolder>data/SqlHistory</HistoryFolder>
<QuerySeparator>;;;</QuerySeparator>
<ResultGridColors Border="#777" HeaderBg="#ffc"
Header="#000" ItemBg="#fff" AltItemBg="#eee" />
</DbUtilConfig>
name attribute is the label displayed in the RadioButtonList control. This is also the key that is associated with history queries (so they remember which database they were executed against).
type attribute can have three possible values: oledb, mssql, odbc (case insensitive).
cs attribute specifies the connection string.
Configuration.AppSettings, you can specify the key name in the csConfKey attribute.
Application variable, you can specify the key name in the csAppKey attribute. Path to the XML file where favourite queries are stored.
Path to the directory where history XML files are stored.
This is the string used to delimit multiple queries. When executing, if there are any occurrences of this string, the query will be split with this string. If there are no occurrences of this string, the code will attempt to split the query with GO statements (e.g., for SQL Server scripts).
Lets you change the colour scheme of the result DataGrids. (By the way, #fff is equivalent to #ffffff).
Border attribute - DataGrid border colour
HeaderBg attribute - DataGrid header background colour
Header attribute - DataGrid header text colour
ItemBg / AltItemBg attributes - DataGrid item / alternating item background colour The JavaScript code to replace the selection in the TEXTAREA with the column name is a fair bit simpler in Internet Explorer compared to that in Firefox:
if (document.all) // IE
window.opener.document.selection.createRange().text = o.innerHTML
else // FF
{
var selStart = queryTextArea.selectionStart
queryTextArea.value =
queryTextArea.value.substring(0, selStart) + o.innerHTML +
queryTextArea.value.substring(queryTextArea.selectionEnd)
queryTextArea.selectionStart = selStart + o.innerHTML.length
queryTextArea.selectionEnd = queryTextArea.selectionStart
}
As you can see, Firefox gives you access to the selection positions, not the selection itself. So you have to use string manipulation to create the new value. Then, I set the selection start/end to select the string that was just inserted.
Where possible, the System.Data interfaces were used, to support different database types. But in some places, the object had to be cast to its actual provider-specific type. Here is an example:
IDbConnection conn = conf.GetConnection(RblWhichDb.SelectedValue);
cmd = conn.CreateCommand();
cmd.CommandText = query;
conn.Open();
try
{
IDataReader reader = cmd.ExecuteReader();
bool hasRows = false;
if (conn is OleDbConnection)
hasRows = ((OleDbDataReader)reader).HasRows;
else if (conn is SqlConnection)
hasRows = ((SqlDataReader)reader).HasRows;
else if (conn is OdbcConnection)
hasRows = ((OdbcDataReader)reader).HasRows;
As I mentioned earlier, a workaround was required for Firefox to toggle the wrapping of the query TEXTAREA. The strange thing is that Firefox does support the wrap attribute when rendering the page, but has absolutely no effect when setting this attribute with JavaScript.
This HTML gives you a TEXTAREA with no text wrapping (i.e., horizontal scrollbar for long lines):
<textarea wrap="false" rows="7" cols="80" id="TxtQuery">
But this JavaScript has no effect on the wrapping:
document.getElementById("TxtQuery").wrap = true
Nor does this:
document.getElementById("TxtQuery").setAttribute("wrap", "true")
I found this really peculiar, but I didn't give up there. I came up with a workaround to re-create the HTML, and assign it as the innerHTML of the parent element:
function toggleWrap(checked)
{
if (window.navigator.userAgent.indexOf("Gecko") != -1)
{
// workaround for Firefox because setting
// 'wrap' attribute just doesn't work :(
var val = document.getElementById("TxtQuery").value
var html = document.getElementById("TxtQuery").parentNode.innerHTML
html = html.replace('wrap="off"', '')
if (!checked)
html = html.substring(0, html.indexOf('| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 30 Aug 2006 Editor: Smitha Vijayan |
Copyright 2006 by Ashley van Gerven Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |