Discussion:
SSE2008: #Tables, Stored Procedures, Avoiding ActiveX
(too old to reply)
Gene Wirchenko
2012-07-31 02:37:02 UTC
Permalink
Dear SQLers:

Having been off on something else, I come back to my slow
progress with JavaScript and SQL Server.

I have a stored procedure for retrieving a row given the key. The
results of this SP (the last table selected AIUI) will be returned to
a Web page.

***** Start of Included Code *****
-- GetPriRow
-- Return the Primus Row Matching the Key
-- Last Modification: 2012-07-30

drop procedure GetPriRow
go
create procedure GetPriRow
(
@theKey varchar(4)
)
as
begin
select * from Primus where PKPri=@theKey
if (@@rowcount=0)
begin
create table #Error
(
OrderBy int not null,
ErrorResponse varchar(max)
)
insert into #Error
(OrderBy,ErrorResponse)
values
(0,'Key not found.')
select * from #Error
return
end
select * from Primus where PKPri=@theKey
end
go
***** End of Included Code *****

This code has issues.

1) I expect to have to create and insert to #Error quite frequently.
I would like a stored procedure for each of these. Unfortunately, due
to the lifetime rules for temporary tables, if I create #Error in its
own SP, it will be deleted as soon as the creation SP terminates. The
above is more verbose than I like. I would prefer to be able to code
something like the following in-line in my SPs:
execute CreErrTbl
execute InsErrRow 0,'Key not found.'
Is there a cleaner way to do this?

2) I query Primus twice, once for the row count and once for real. I
do wish to catch no rows as an error condition. I wish to avoid race
conditions. (I think I have a race condition here in the case of the
row being deleted just after the first time, but before the second.
Am I correct in thinking this? If so, how do I correct it?)

3) The front-end will be a Web page. I want to retrieve a row, edit
it, and write it back. I would like that any changes in the meantime
are not overwritten. As far as I can see, this is not going to work
to protect meantime changes, and I need to do something more.

Can I lock the read row? If so:
a) Can I release the lock after updating the row? This would be in
a separate stored procedure and a different XMLHttpRequest.
b) Can I have the row lock expire after a period of time (say, 15
minutes)? Someone could close his browser after reading a row, and I
do not want the row lock kept indefinitely.

4) I would like to avoid using ActiveX to communicate between the
Web page and SQL Server and preferably without having to add more
software to the server. Otherwise, my app is going to be limited to
IE. I have been unable to find any details on how to do this.
Pointers would be appreciated.

For all of the above, what is the stuff called (so I can search
it down (though good links will be appreciated)), and what is the
syntax?

Are there any other details I should give? Are there any other
questions that I should be asking?

Sincerely,

Gene Wirchenko
Gene Wirchenko
2012-07-31 02:47:22 UTC
Permalink
Post by Gene Wirchenko
Having been off on something else, I come back to my slow
progress with JavaScript and SQL Server.
I forgot another point:

5) What additional error handling do I need so that if something
blows up, I can give an intelligent response to the browser? (Even if
said response is only that SQL Server has thrown an error.)

Sincerely,

Gene Wirchenko
Erland Sommarskog
2012-07-31 09:08:01 UTC
Permalink
Post by Gene Wirchenko
1) I expect to have to create and insert to #Error quite frequently.
I would like a stored procedure for each of these. Unfortunately, due
to the lifetime rules for temporary tables, if I create #Error in its
own SP, it will be deleted as soon as the creation SP terminates. The
above is more verbose than I like. I would prefer to be able to code
execute CreErrTbl
execute InsErrRow 0,'Key not found.'
Is there a cleaner way to do this?
Why wouid you creaet the temp table at all? Why not just return a result set

SELECT 0 AS OrderBy, 'Key not found.' AS ErrorReponse

Also, most clients gets confused if a stored procedure returns two results
sets with different shape. Of course, it's perfectly manageable if you
program the client correctly, but it's a little dubious.
Post by Gene Wirchenko
2) I query Primus twice, once for the row count and once for real. I
do wish to catch no rows as an error condition. I wish to avoid race
conditions. (I think I have a race condition here in the case of the
row being deleted just after the first time, but before the second.
Am I correct in thinking this? If so, how do I correct it?)
So the purpose with the above procedure is to check for existence? Why in
that case not use

SELECT @output = CASE WHEN EXISTS (select *
from Primus where PKPri=@theKey)
THEN 1
ELSE 0
END

And this scraps the result set above entirely. The stored procedure have no
reason to ponder whether existence is an error not. The job of the procedure
is return whether there is a row or not. It's up to the caller to consider
that to be an error or not.

As for your actual question, the answer is that if you are in a transaction
and you add the table hint (SERIALISABLE) you will prevent a row to be
Post by Gene Wirchenko
3) The front-end will be a Web page. I want to retrieve a row, edit
it, and write it back. I would like that any changes in the meantime
are not overwritten. As far as I can see, this is not going to work
to protect meantime changes, and I need to do something more.
a) Can I release the lock after updating the row? This would be in
a separate stored procedure and a different XMLHttpRequest.
b) Can I have the row lock expire after a period of time (say, 15
minutes)? Someone could close his browser after reading a row, and I
do not want the row lock kept indefinitely.
Yes, you can lock a row if you read it in a transction and the isolation
level is at least PEPEATABLE READ. The row will be released when you commit.

BUT DON'T DO THIS! Having a transaction in progress when you are waiting for
user input is an absolute no-no.

The most commonly used solution is optimisitic concurrency. You add a
timestamp (a.k.a rowversion) column to the table. This column is auto-
matically updated with a database-unique monotonically growing value when a
row is updated. Thus, you read the timestamp value and when you write back
you compare, and if they are different someone else has come in between.

If you want pessimistic concunrrency, you will have to roll your own.
Post by Gene Wirchenko
4) I would like to avoid using ActiveX to communicate between the
Web page and SQL Server and preferably without having to add more
software to the server. Otherwise, my app is going to be limited to
IE. I have been unable to find any details on how to do this.
Pointers would be appreciated.
Sounds like a question for a different newsgroup.
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
Bob Barrows
2012-07-31 18:25:12 UTC
Permalink
Post by Gene Wirchenko
4) I would like to avoid using ActiveX to communicate between the
Web page and SQL Server and preferably without having to add more
software to the server. Otherwise, my app is going to be limited to
IE.
The only time scripting language will restrict you to IE is if you use
vbscript in client-side code.

There are no such restrictions in server-side code: the language being used
in the server-side code to generate html to be sent to the browser is
completely browser-independent. The html that is generated is what can limit
the browser being used. Browser-restricted html can be created by any
scripting language.

So, depending on what you mean by "ActiveX" (are you talking about ADO, or
perhaps ADO.Net? ), its use or avoidance will not have an effect on what
browsers can be used. Even if you are planning to directly access the
database from the client-side code (which can really only work in a WAN
environment) it is certainly possible to use ADO in javascript, which is
browser-independent.
Gene Wirchenko
2012-07-31 22:02:29 UTC
Permalink
On Tue, 31 Jul 2012 14:25:12 -0400, "Bob Barrows"
Post by Bob Barrows
Post by Gene Wirchenko
4) I would like to avoid using ActiveX to communicate between the
Web page and SQL Server and preferably without having to add more
software to the server. Otherwise, my app is going to be limited to
IE.
The only time scripting language will restrict you to IE is if you use
vbscript in client-side code.
There are no such restrictions in server-side code: the language being used
in the server-side code to generate html to be sent to the browser is
completely browser-independent. The html that is generated is what can limit
the browser being used. Browser-restricted html can be created by any
scripting language.
So, depending on what you mean by "ActiveX" (are you talking about ADO, or
perhaps ADO.Net? ), its use or avoidance will not have an effect on what
browsers can be used. Even if you are planning to directly access the
database from the client-side code (which can really only work in a WAN
environment) it is certainly possible to use ADO in javascript, which is
browser-independent.
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have. If there is another way of doing it, I would
be delighted to find out how.

Sincerely,

Gene Wirchenko
Jeroen Mostert
2012-07-31 22:26:43 UTC
Permalink
Post by Gene Wirchenko
On Tue, 31 Jul 2012 14:25:12 -0400, "Bob Barrows"
Post by Bob Barrows
Post by Gene Wirchenko
4) I would like to avoid using ActiveX to communicate between the
Web page and SQL Server and preferably without having to add more
software to the server. Otherwise, my app is going to be limited to
IE.
The only time scripting language will restrict you to IE is if you use
vbscript in client-side code.
There are no such restrictions in server-side code: the language being used
in the server-side code to generate html to be sent to the browser is
completely browser-independent. The html that is generated is what can limit
the browser being used. Browser-restricted html can be created by any
scripting language.
So, depending on what you mean by "ActiveX" (are you talking about ADO, or
perhaps ADO.Net? ), its use or avoidance will not have an effect on what
browsers can be used. Even if you are planning to directly access the
database from the client-side code (which can really only work in a WAN
environment) it is certainly possible to use ADO in javascript, which is
browser-independent.
JavaScript is neither browser independent (subtle but important differences
exist), nor does support for instantiating ActiveX-objects exist outside of
JScript and Internet Explorer. Thank heavens for small favors.

JScript does exist as its own engine in the Windows Scripting Host, but then
that's not a browser.
Post by Gene Wirchenko
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have.
Like Bob said, you create these objects on the server side, using
Server.CreateObject(). The browser never sees these objects. In fact, the
browser doesn't know a database is involved at all -- the server is the one
contacting the database and formatting the data as HTML. The communication
between the browser and the site is limited to HTTP.

Although it is in fact possible to use these components client-side (in an
IE intranet only), that's like enjoying hot cocoa by snorting it up your
nose: weird, uncomfortable and altogether missing the point. Basically, it's
a terrifically inconvenient way of writing an application you could write
much better using almost any other client-side technology, like .NET.

There is no browser-independent way of accessing a database from the client
side, unless you consider HTML5's forays in that area (web SQL databases,
since abandoned). Even then it's about local databases, not database servers.
--
J.
Gene Wirchenko
2012-08-01 00:43:58 UTC
Permalink
On Wed, 01 Aug 2012 00:26:43 +0200, Jeroen Mostert
[snip]
Post by Jeroen Mostert
Post by Gene Wirchenko
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have.
Like Bob said, you create these objects on the server side, using
Server.CreateObject(). The browser never sees these objects. In fact, the
browser doesn't know a database is involved at all -- the server is the one
contacting the database and formatting the data as HTML. The communication
between the browser and the site is limited to HTTP.
I know that I create objects on the server side. I also have to
create objects on the browser side. At this point in time, I do not
have an alternative. I have been looking for one.

I need data validation at the browser level.
Post by Jeroen Mostert
Although it is in fact possible to use these components client-side (in an
IE intranet only), that's like enjoying hot cocoa by snorting it up your
nose: weird, uncomfortable and altogether missing the point. Basically, it's
a terrifically inconvenient way of writing an application you could write
much better using almost any other client-side technology, like .NET.
There is no browser-independent way of accessing a database from the client
side, unless you consider HTML5's forays in that area (web SQL databases,
since abandoned). Even then it's about local databases, not database servers.
I do not care so much about browser-independent as much as I
would like to be able to use more than just IE.

Sincerely,

Gene Wirchenko
Bob Barrows
2012-08-01 10:29:59 UTC
Permalink
Post by Gene Wirchenko
On Wed, 01 Aug 2012 00:26:43 +0200, Jeroen Mostert
[snip]
Post by Jeroen Mostert
Post by Gene Wirchenko
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have.
Like Bob said, you create these objects on the server side, using
Server.CreateObject(). The browser never sees these objects. In
fact, the browser doesn't know a database is involved at all -- the
server is the one contacting the database and formatting the data as
HTML. The communication between the browser and the site is limited
to HTTP.
I know that I create objects on the server side. I also have to
create objects on the browser side. At this point in time, I do not
have an alternative. I have been looking for one.
I need data validation at the browser level.
Several option to avoid the need to directly query the database from the
browser:
1. Leverage some data caching in arrays on the client-side (provided the
data sets are not too large to overload the browser) to perform some of the
validations.
2. Use technology like JSON or AJAX to send requests to and receive
responses from a server page without needing to submit and reload the client
page.
3. There is also web service technology that can be leveraged

Seriously, there are people who are much more knowledgeable about this stuff
in relevant forums than I am (it's been several years since I created a web
application so I have failed to keep up in the technology, and I've never
created an internet application) - you really need to start asking these
questions in such a forum.
Post by Gene Wirchenko
Post by Jeroen Mostert
Although it is in fact possible to use these components client-side
(in an IE intranet only), that's like enjoying hot cocoa by snorting
it up your nose: weird, uncomfortable and altogether missing the
point. Basically, it's a terrifically inconvenient way of writing an
application you could write much better using almost any other
client-side technology, like .NET.
Except for the inconvenience of having to deploy all these fat clients to
all the user desktops. My company made the decision years ago to only
support IE. Yes, there have been some unhappy users, but we do have a
captive audience who need to use these applications to do their jobs, and we
do not have an army of testers and programmers to rewrite our applications
to ensure all browsers can be supported.
Post by Gene Wirchenko
Post by Jeroen Mostert
There is no browser-independent way of accessing a database from the
client side, unless you consider HTML5's forays in that area (web
SQL databases, since abandoned). Even then it's about local
databases, not database servers.
I do not care so much about browser-independent as much as I
would like to be able to use more than just IE.
Well, I thnk you have the only answer we can give you.
Jeroen Mostert
2012-08-01 18:40:58 UTC
Permalink
Post by Bob Barrows
Post by Gene Wirchenko
On Wed, 01 Aug 2012 00:26:43 +0200, Jeroen Mostert
[snip]
Post by Bob Barrows
Post by Gene Wirchenko
Post by Jeroen Mostert
Although it is in fact possible to use these components client-side
(in an IE intranet only), that's like enjoying hot cocoa by snorting
it up your nose: weird, uncomfortable and altogether missing the
point. Basically, it's a terrifically inconvenient way of writing an
application you could write much better using almost any other
client-side technology, like .NET.
Except for the inconvenience of having to deploy all these fat clients to
all the user desktops.
At our shop we've solved this problem by running the clients from a network
share (the clients can copy themselves locally before starting properly, so
they don't lock the executable out of updating). Of course, that has its own
perils and pitfalls, but just to put it out there.

Our standard model is a browser front-end and a website back-end, though. As
things grow more complex, the benefits of a separate, centralized layer for
data access quickly kick in.
Post by Bob Barrows
My company made the decision years ago to only support IE. Yes, there
have been some unhappy users, but we do have a captive audience who need
to use these applications to do their jobs, and we do not have an army of
testers and programmers to rewrite our applications to ensure all
browsers can be supported.
There is nothing wrong with the decision to use only IE in an intranet
environment, especially if you have earlier already committed to IE-specific
stuff like ActiveX.

That said, that still doesn't mean it's a good idea to use ADO directly from
client-side IE. If possible, I'd still prefer a separate ActiveX-control
that wraps this stuff so you still have the benefit of updating over the
wire without being forced to write your application in JScript or VBScript.
But that's just developer preference, you could always switch between these
solutions.
--
J.
Erland Sommarskog
2012-08-01 19:02:06 UTC
Permalink
Post by Jeroen Mostert
That said, that still doesn't mean it's a good idea to use ADO directly
from client-side IE.
I did not know that this was even possible, but it strikes me as an
utterly bad idea of having a direct connection from browser to database.

One of the great benefits with a three-tiered application is that you put
the database server where users cannot see it on the network, and thus
connect to it. Even in an intranet app can benefit from security.
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
Bob Barrows
2012-08-01 20:02:45 UTC
Permalink
Post by Jeroen Mostert
Post by Bob Barrows
My company made the decision years ago to only support IE. Yes, there
have been some unhappy users, but we do have a captive audience who
need to use these applications to do their jobs, and we do not have
an army of testers and programmers to rewrite our applications to
ensure all browsers can be supported.
There is nothing wrong with the decision to use only IE in an intranet
environment, especially if you have earlier already committed to
IE-specific stuff like ActiveX.
That said, that still doesn't mean it's a good idea to use ADO
directly from client-side IE.
Agreed. Client-side validation is just not important enough to open a
potential security hole.
Jeroen Mostert
2012-08-01 18:29:38 UTC
Permalink
On 2012-08-01 02:43, Gene Wirchenko wrote:
[snip]
Post by Gene Wirchenko
I do not care so much about browser-independent as much as I
would like to be able to use more than just IE.
Then you are, as they say, shit outta luck. If you insist on client-side
database access from a browser, it's IE or nothing.
--
J.
Erland Sommarskog
2012-08-01 07:14:42 UTC
Permalink
Post by Gene Wirchenko
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have. If there is another way of doing it, I would
be delighted to find out how.
Old ADO is a technology that dead in the sense that there is no further
development with it - and has not been for a decade or so. It exists
in legacy applications, but it is nothing you should use for a new
application in 2012. ADO was crap already in its heyday, and now it also
suffers from lack of support for new features in SQL Server.

You should use ADO .Net, or possibly JDBC or PHP as your data access API.
(The old thing old ADO and ADO .Net has in common are three letters.)

As for being browser-independent or not - if you make your application
to run on IE only, you will have to deal with irritated users who prefers
to use a different browser.
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
Jason Keats
2012-08-04 08:14:03 UTC
Permalink
Post by Erland Sommarskog
Post by Gene Wirchenko
My understanding is that in order to access the data with the
browser, I have to create an ADODB.Connection object and an
ADODB.Recordset object using ActiveXObject() which Firefox (for
example) does not have. If there is another way of doing it, I would
be delighted to find out how.
Old ADO is a technology that dead in the sense that there is no further
development with it - and has not been for a decade or so. It exists
in legacy applications, but it is nothing you should use for a new
application in 2012. ADO was crap already in its heyday, and now it also
suffers from lack of support for new features in SQL Server.
You should use ADO .Net, or possibly JDBC or PHP as your data access API.
(The old thing old ADO and ADO .Net has in common are three letters.)
As for being browser-independent or not - if you make your application
to run on IE only, you will have to deal with irritated users who prefers
to use a different browser.
ADO was installed as part of MDAC, but is now part of WDAC which comes
with the operating system of Windows Vista and later. ADO is not yet
deprecated, and is (AFAIK still) THE way to access your SQL Server data
- if you're not using a .NET programming language.
Erland Sommarskog
2012-08-04 19:15:40 UTC
Permalink
Post by Jason Keats
ADO was installed as part of MDAC, but is now part of WDAC which comes
with the operating system of Windows Vista and later. ADO is not yet
deprecated, and is (AFAIK still) THE way to access your SQL Server data
- if you're not using a .NET programming language.
No, that would be ODBC.

ADO does not fully support new data types added to SQL Server. The ones
that are supported are only because they fit into the OLE DB framework
at the time, for instance the date data type. (Where as time does not
work, since the time data type in SQL Server does not mach TIME in
OLE DB.)
--
Erland Sommarskog, SQL Server MVP, ***@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
Loading...