On 12 Mar 2004 20:17:59 GMT, Joe Celko wielded his Keyboard of Typing
to write:
[quoted text, click to view] >>> I want to replace this with an equivalent ANSI
>standard query, but I fail to see how to do this. <<
>
>Here is a shot at it, based on absolutely no DDL and a vague narrative
>description.
You've got a point there. The DDL is at the end of this message.
[quoted text, click to view] > Well, first thing to get to ANSI/ISO is to replace #
>prefixes with something else ("_nbr"? ) and the leading _ has to go.
In SQL Server, all temporary tables need to start with the hash
symbol. AFAIC, this may or may not be different from ANSI, but I need
it this way to ensure that the temporary table is stored in tempdb,
not in the actual database.
I can't find a leading _; maybe yoou meant a leading #?
[quoted text, click to view] >Here is my guess:
>
>UPDATE Rx
>SET isgxwapplic -- storing flags???
> = CASE WHEN
> EXISTS
> (SELECT *
> FROM BRrol, #brrol AS BR
> WHERE BR.br_id = BRrol.br_id
> AND BR.brtype = 'virtual'
> AND Rx.rol_id = BRrol.rol_id)
> THEN 'y' ELSE 'n' END;
Not good at all. It will update all rows in the RolX table instead of
affecting only the columns that can be matched against #BrRol. I just
reread my original post and now see that I forgot to add that it is
very important that other rows in RolX stay unchanged. That's not a
performance issue but a design demand.
[quoted text, click to view] >An EXISTS() is usually much faster than counting rows.
It is if you only want to check for existance. I need to check for the
existance of exactly one row that matches the criteria, no less but no
more either.
[quoted text, click to view] >>> * RolX is a specialization of another table (Rol - not used in this
>query). Both Rol and RolX have the column RolId as primary key. <<
>
>You mean a VIEW; surely you did not put the same data in TWO tables!!
If I meant a view, I would have written it. It's a specialization (aka
a subtype, depending on your favorite design method), holding data
that applies to only a small subset of the rows in the main table. Not
the same data, of course, but extra data. If you have data on several
million persons and you need to store 10 extra columns for only the
persons that are male, white, living in Wyoming and aged between 40
and 45, you could add 10 nullable columns to the table for persons,
but I would add a new table WhiteWyomingMiddleAgedMale and add the new
columns into that table.
[quoted text, click to view] >>> holding only the rows from BrRol that have been changed since the
>IsGxwApplic column was last recalculated. <<
>
>This is how we used to do it when we had to use punch cards and magnetic
>tape systems. Your RDBMS should not store computed columns.
As a rule of thumb, yes. As an ever-true-beyond-any-doubt gospel, no.
If the calculation is complex, often read and changes are rare,
storing a computed column is often the better choice.
If the calculation is complex or needs lots of data and read access to
the data is time-critical, computed columns should be stored (how long
do you think the queue before the cash dispenser would grow if your
bank decided not to store the current balance, since it can be
computed from the transaction history)
If the calculation uses data that is not stored, a computed column is
the only choice. (E.g. a timestamp or the userid of the user
performing an update)
If it is necessary that the computed column is only updated at
specific intervals and remeins untouched in between, even if the
underlying data changes, it has to be stored.
If changes in the computed column have to fire a trigger, the computed
column has to be stored. (AFAIK, it is not possible to fire a trigger
on changes in a view. At least not in MS SQL Server 2000)
[quoted text, click to view] > This whole
>thing should be in a VIEW that never needs to be updated.
If I did that, it would cause the value of IsGxwApplic to change
before it should and it would mean that some important reports that
are made when the UPDATE trigger for RolX fires would not be made
anymore.
I'd be jobless before I could say "Social security". <g>
[quoted text, click to view] >
>--CELKO--
> ===========================
> Please post DDL, so that people do not have to guess what the keys,
>constraints, Declarative Referential Integrity, datatypes, etc. in your
>schema are.
As promised: here's the relevant part of the DDL
CREATE TABLE Rol (RolId INT NOT NULL PRIMARY KEY,
several other columns)
CREATE TABLE RolX (RolId INT NOT NULL PRIMARY KEY,
IsGxwApplic CHAR(1) NULL,
several other columns,
FOREIGN KEY (RolId) REFERENCES Rol(RolId))
CREATE TABLE Br (BrId INT NOT NULL PRIMARY KEY,
BrType CHAR(10) NOT NULL,
several other columns)
CREATE TABLE BrRol (BrId INT NOT NULL,
RolId INT NOT NULL,
PRIMARY KEY (BrId, RolId)
FOREIGN KEY (BrId) REFERENCES Br(BrId)
FOREIGN KEY (RolId) REFERENCES Rol(RolId))
CREATE TABLE #BrRol (BrId INT NOT NULL,
RolId NOT NULL,
PRIMARY KEY (BrId, RolId))
/* No foreign key, as corresponding Br and Rol
may already have been removed! */
Best, Hugo
--