A frequent question that pops up on discussion forums is how to serve an image that is stored in a SQL Server table from an ASP.Net application. Unfortunately the answer is almost always wrong, as the prevalent solution involves copying the entire image file into memory before returning it to the client. This solution works fine when tested with a light load and returning few small images. But in production environment the memory consumption required by all those image files stored as byte arrays in memory causes serious performance degradation. A good solution must use streaming semantics, transferring the data in small chunks from the SQL Server to the HTTP returned result.
The SqlClient components do offer streaming semantics for large result sets, including large BLOB fields, but the client has to specifically ask for it. The ‘secret ingredient’ is the passing in the CommandBehavior.SequentialAccess flag to the SqlCommand.ExecuteReader:
Provides a way for the DataReader to handle rows that contain columns with large binary values. Rather than loading the entire row, SequentialAccess enables the DataReader to load data as a stream. You can then use the GetBytes or GetChars method to specify a byte location to start the read operation, and a limited buffer size for the data being returned.
An ASP.Net MVC virtual Media folder backed by SQL Server
Lets say we want to have a virtual Media folder in an ASP.Net MVC site, serving the files from a SQL Server database. A GET request for an URL like "http://site/Media/IMG0042.JPG" should return the content of the file named IMG0042.JPG from the database. A POST request to the URL "http://site/Media" which contains an embedded file should insert this new file in the database and redirect the response to the newly added file virtual path. This is how our upload HTML form looks like:
Read the rest of this entry »
Posted in Samples, Tutorials | 4 Comments »
Query Notifications is the SQL Server feature that allows a client to subscribe to notifications that are sent when data in the database changes irrelevant of how that change occurs. I have talked before about how Query Notifications works in the article The Mysterious Notification. This feature was designed specifically for client side cache invalidation: the applications runs a query, gets back the result and stores it in the cache. Whenever the result is changed because data was updated, the application will be notified and it can invalidate the cached result.
Leveraging Query Notifications from the managed clients is very easy due to the dedicated SqlDependency class that takes care of a lot of the details needed to be set up in place in order to be able to receive these notifications. But the MSDN examples and the general community know how with SqlDepenendency is geared toward straight forward usage, by attaching it to a SqlCommand object.
Read the rest of this entry »
Posted in Announcements, CodeProject, Samples, Tutorials | 1 Comment »
A very common question asked on all programming forums is how to implement queues based on database tables. This is not a trivial question actually. Implementing a queue backed by a table is notoriously difficult, error prone and susceptible to deadlocks. Because queues are usually needed as a link between various processing stages in a workflow they operate in highly concurrent environments where multiple processes enqueue rows into the table while multiple processes attempt to dequeue these rows. This concurrency creates correctness, scalability and performance challenges.
But since SQL Server 2005 introduced the OUTPUT clause, using tables as queues is no longer a hard problem. This fact is called out in the OUTPUT Clause topic in BOL:
You can use OUTPUT in applications that use tables as queues, or to hold intermediate result sets. That is, the application is constantly adding or removing rows from the table… Other semantics may also be implemented, such as using a table to implement a stack.
The reason why OUTPUT clause is critical is that it offers an atomic destructive read operation that allows us to remove the dequeued row and return it to the caller, in one single statement.
Read the rest of this entry »
Posted in CodeProject, Samples, Tutorials | 2 Comments »
The question of comparing the MAX types (VARCHAR, NVARCHAR, VARBINARY) with their non-max counterparts is often asked, but the answer usually gravitate around the storage differences. But I’d like to address the point that these types have inherent, intrinsic performance differences that are not driven by different storage characteristics. In other words, simply comparing and manipulating variables and columns in T-SQL can yield different performance when VARCHAR(MAX) is used vs. VARCHAR(N).
Assignment
First comparing simple assignment, assign a value to a VARBINARY(8000) variable in a tight loop:
Read the rest of this entry »
Posted in CodeProject, Samples, Tutorials | 1 Comment »
Quick trivia: what is the result of running SELECT COUNT(*);
?
That’s right, no FROM
clause, just COUNT(*)
. The answer may be a little bit surprising, is 1. When you query SELECT 1;
the result is, as expected, 1. And SELECT 2;
will return 2. So SELECT COUNT(2);
returns, as expected, 1, after all it counts how many rows are in the result set. But SELECT COUNT(*);
has a certain smell of voo-doo to it. Ok, is the * project operator, but project from… what exactly? It feels eerie, like a count is materialized out of the blue.
How about SELECT COUNT(*) [MyTable]
. Well, that’s actually just a shortcut for SELECT COUNT(*) AS [MyTable]
, so it still returns 1 but in a column named MyTable
. Now you understand why my heart missed a bit when I checked how I initialized a replication subscription and I forgot to type in FROM
…
Posted in Samples | 3 Comments »
Code on GitHub: rusanu/async_tsql
I have posted previously an example how to invoke a procedure asynchronously using service Broker activation. Several readers have inquired how to extend this mechanism to add parameters to the background launched procedure.
Passing parameters to a single well know procedure is easy: the parameters are be added to the message body and the activated procedure looks them up in the received XML, passing them to the called procedure. But is significantly more complex to create a generic mechanism that can pass parameters to any procedure. The problem is the type system, because the parameters have unknown types and the activated procedure has to pass proper typed parameters to the invoked procedure.
A generic solution should accept a variety of parameter types and should deal with the peculiarities of Transact-SQL parameters passing, namely the named parameters capabilities. Also the invocation wrapper usp_AsyncExecInvoke should directly accept the parameters for the desired background procedure. After considering several alternatives, I settled on the following approach:
Read the rest of this entry »
Posted in Samples, Tutorials | 5 Comments »
Code on GitHub: rusanu/async_tsql
Update: a version of this sample that accepts parameters is available in the post Passing Parameters to a Background Procedure
Recently an user on StackOverflow raised the question Execute a stored procedure from a windows form asynchronously and then disconnect?. This is a known problem, how to invoke a long running procedure on SQL Server without constraining the client to wait for the procedure execution to terminate. Most times I’ve seen this question raised in the context of web applications when waiting for a result means delaying the response to the client browser. On Web apps the time constraint is even more drastic, the developer often desires to launch the procedure and immediately return the page even when the execution lasts only few seconds. The application will retrieve the execution result later, usually via an Ajax call driven by the returned page script.
Read the rest of this entry »
Posted in CodeProject, Samples, Tutorials | 7 Comments »
I wanted to use a template for writing procedures that behave as intuitively as possible in regard to nested transactions. My goals were:
- The procedure template should wrap all the work done in the procedure in a transaction.
- The procedures should be able to call each other and the calee should nest its transaction inside the outer caller transaction.
- The procedure should only rollback its own work in case of exception, if possible.
- The caller should be able to resume and continue even if the calee rolled back its work.
My solution is to use a either a transactions or a savepoint, depending on the value of @@TRANCOUNT at procedure start. The procedures start a new transaction if no transaction is pending. Otherwise they simply create a savepoint. On exit the procedure commits the transaction they started (if they started one), otherwise they simply exit. On exception, if the transaction is not doomed, the procedure either rolls back (if it started the transaction), or rolls back to the savepoint it created (if calee already provided a transaction).
Read the rest of this entry »
Posted in CodeProject, Samples, Tutorials | 2 Comments »
Whenever I’m faced with a project in which I have to create a lot of tedious and repeating code I turn to the power of XML and XSLT. Rather than copy/paste the same code over and over again, just to end up with a refactoring and maintenance nightmare, I create an XML definition file and an XSLT transformation. I am then free to add new elements to the XML definition or to change the way the final code is generated from the XSLT transformation. This can be fully integrated with Visual Studio so that the code generation happens at project build time and the environment shows the generated code as a dependency of the XML definition file.
A few examples of how I’m using this code generation via XSLT are:
- Data Access Layer
- I know this will raise quite a few eyebrows, but I always write my own data access layer from scratch and is generated via XSLT.
- Performance Counters
- I create all my performance counters objects via XSLT generation, automating the process of defining/installing them and the access to emit and consume the counter values.
- Wire Frames
- In any project that has networking communication I access the wire format from classes generated via XSLT that take care of serialization and validation.
For example I’ll show how to create a class library that can be added to your project to expose Performance Counters from your application.
Read the rest of this entry »
Posted in Samples | Comments Off on Using XSLT to generate Performance Counters code
One of the interesting features of the OUTPUT clauses introduced in SQL Server 2005 is that one can actualy chain DML statements into one complex statement that operates updates on several tables at once. Say we have a table with customer data and a process that has to bill each customer periodically. The ‘billing’ process consist of an update on the table (say extend the subscription date), but the billing has to be processed separately. Consider an example where the processing involves a Web call to a bank portal to charge a credit card and, like all HTTP calls, it has the potential to fail. So we have two tables like this:
Read the rest of this entry »
Posted in Samples | 2 Comments »