![]() | |
![]() |
| | Thread Tools | Display Modes |
#11
| |||
| |||
|
|
Why did you store a computed column in a table? Have you ever been to client for performnace tunning, are you familiar how |
|
Why did you store a computed column in a table? SQL is a declarative language. But you are using procedural code all over the place, in a TRIGGER and a UDF! You are still thinking as if you were writing for magnetic tape files or punch cards. You even use the word "record" because your mindset is all wrong. There is no such thing as an IDENTITY field. First of all, a column is nothing like a field. It is a proprietary, non-relational table property. Programmers who do not know RDBMS often use it to get a "record number" so that they can make their SQL look like a sequential file -- magnetic tape files or punch cards. The DDL skeleton would be something like this: CREATE TABLE Clients (client_id CHAR(7) NOT NULL PRIMARY KEY CHECK(client_id LIKE '<pattern>'), signup_date DATE DEFAULT CURRENT_DATE NOT NULL, (<build card number here>) AS card_nbr, etc); You need a way of getting a client identifier that can be validated and verified. IDENTITY has neither and it cannot even give you consecutive numbers. I would not expose the client id in the card number -- do you write your PIN on your bank card? You need to learn how to follow ISO-11179 data element naming conventions and formatting rules. Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect. |
#12
| |||
| |||
|
|
Thanks, I needed that! How did you know I am old enough to have used punched cards on a DEC System 10? But seriously: |
|
- Consecutive numbers are not a requirement, but after the testing is done and the database is on a production server, I expect it will be. I was somewhat surprised by the SQL Server behavior because I expected the operation to be rolled back on error. |
#13
| |||
| |||
|
|
--CELKO-- Why did you store a computed column in a table? Have you ever been to client for performnace tunning, are you familiar how SQL Server estimates the number of rows satisfying this condition using the column statistics ? What do you think about those approaches? WHERE UnitPrice * Quantity > 100 and ADDING a computed column on AS UnitPrice * Quantity SQL Server will detect the use of the computed column in the second example and it will create statistics on the computed column. The statistics will allow the optimizer to determine the appropriate cardinality estimation on the filter. "--CELKO--" <jcelko212 (AT) earthlink (DOT) net> wrote in message news:687c5bf6-50b5-4a56-ac28-30a31d7c9898 (AT) 35g2000yqa (DOT) googlegroups.com... Why did you store a computed column in a table? SQL is a declarative language. But you are using procedural code all over the place, in a TRIGGER and a UDF! You are still thinking as if you were writing for magnetic tape files or punch cards. You even use the word "record" because your mindset is all wrong. There is no such thing as an IDENTITY field. First of all, a column is nothing like a field. It is a proprietary, non-relational table property. Programmers who do not know RDBMS often use it to get a "record number" so that they can make their SQL look like a sequential file -- magnetic tape files or punch cards. The DDL skeleton would be something like this: CREATE TABLE Clients (client_id CHAR(7) NOT NULL PRIMARY KEY CHECK(client_id LIKE '<pattern>'), signup_date DATE DEFAULT CURRENT_DATE NOT NULL, (<build card number here>) AS card_nbr, etc); You need a way of getting a client identifier that can be validated and verified. IDENTITY has neither and it cannot even give you consecutive numbers. I would not expose the client id in the card number -- do you write your PIN on your bank card? You need to learn how to follow ISO-11179 data element naming conventions and formatting rules. Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect. |
#14
| ||||||
| ||||||
|
|
I needed that! How did you know I am old enough to have used punched cards on a DEC System 10? |
|
- I need the computed field [sic] in there because another dumb ID card printing program will use it to print an ID card. |
|
Also it is a foreign key field [sic] in other tables that contain data about the client. The id card is used later to retrieve data using either a barcode or a Mag card reader. |
|
- I use the term IDENTITY because that is what MS calls an auto-increment field [sic]. |
|
- Consecutive numbers are not a requirement, but after the testing is done and the database is on a production server, I expect it will be. |

|
- This is not my day job but I am beginning to like it :-) |
#15
| |||
| |||
|
|
That reminds me - the left/right pair of the nested sets model you popularize cannot be "validated" and "verified" because on day 1 the left/right pair might be 12,1 and the next day or even the next minute it might be 12,5; so, any table using the left/right pairing is now disconnected and orphaned. |
|
The stable and unchangeable value returned by IDENTITY on insert can easily be verified back - once inserted the value can never change. |
|
Gaps occur only on rollbacks but the benefits in concurrency massively out weigh this problem; the architect needs to balance that with a "real" need for an incrementor without gaps in which case they must destroy concurrency and use MAX( x ) + 1 with some severe locking. |
#16
| ||||
| ||||
|
|
No, on Day #1, the hierarchical pair (12, 1) is rejected because it fails validation. The pair must conform to the constraint (lft rgt). As I have said for over ten years, you should do this in Full Standard SQL-99 with a CHECK() or CREATE ASSERTION. In SQL Server and other lesser SQLs, you can fake it with a VIEW, like this skeleton |
|
Actually, this forum has a quite a few postings from forgetting to set the right flags in BCP and scrambling the IDENTITY values. There is no "trusted source" for verification since the IDENTITY is a local table property. Compare this to the manufacturer for a part number |
|
I have the CREATE SEQUENCE statement when I am using DB2, Oracle, etc. I do not know if/when SQL Server will add it, but we did get the MERGE and ANSI/ISO temporal stuff a few decades late, so I have hope. |
|
That reminds me - the left/right pair of the nested sets model you popularize cannot be "validated" and "verified" because on day 1 the left/right pair might be 12,1 and the next day or even the next minute it might be 12,5; so, any table using the left/right pairing is now disconnected and orphaned. No, on Day #1, the hierarchical pair (12, 1) is rejected because it fails validation. The pair must conform to the constraint (lft rgt). As I have said for over ten years, you should do this in Full Standard SQL-99 with a CHECK() or CREATE ASSERTION. In SQL Server and other lesser SQLs, you can fake it with a VIEW, like this skeleton CREATE TABLR RawTree (node_id char(10) DEFAULT 'VACANT' NOT NULL REFERENCES Nodes (node_id) ON UPDATE CASCADE ON DELETE SET DEFAULT, -- PRIMARY KEY () -- business rules allow node_id or (lft, rgt), lft INTEGER NOT NULL CHECK (lft > 0), rgt INTEGER NOT NULL CHECK (rgt > 1), CONSTRAINT valid_pair_ordering CHECK (lft < rgt), CONSTRAINT valid_pair_spacing -- business rules for no gaps? CHECK ((rgt - lft) % 2 = 0); Now fake the CREATE ASSERTION: CREATE VIEW ValidatedTree (node_id, lft, rgt) AS SELECT node_id, lft, rgt FROM Raw_Tree WHERE NOT EXISTS -- no range overlaps (SELECT * FROM Raw_Tree AS T1, Raw_Tree AS T2 WHERE T1.lft BETWEEN T2.lft AND T2.rgt AND T1.rgt BETWEEN T2.lft AND T2.rgt AND (T1.lft <> T2.lft OR T1.rgt <> T2.rgt)); Warning, if you get directly the Raw_Tree base table, you can mess up things. You need DDL, DML and DCL working together. For kicks, write the same validations for the adjacency list model. The best I was able to do was a trigger with procedural code to traverse the tree looking for cycles. The stable and unchangeable value returned by IDENTITY on insert can easily be verified back - once inserted the value can never change. Actually, this forum has a quite a few postings from forgetting to set the right flags in BCP and scrambling the IDENTITY values. There is no "trusted source" for verification since the IDENTITY is a local table property. Compare this to the manufacturer for a part number Gaps occur only on rollbacks but the benefits in concurrency massively out weigh this problem; the architect needs to balance that with a "real" need for an incrementor without gaps in which case they must destroy concurrency and use MAX( x ) + 1 with some severe locking. I have the CREATE SEQUENCE statement when I am using DB2, Oracle, etc. I do not know if/when SQL Server will add it, but we did get the MERGE and ANSI/ISO temporal stuff a few decades late, so I have hope. |
#17
| |||
| |||
|
|
You cannot use BCP or BULK INSERT for the method you propose, the MAX(col) + 1; with that method you are limited to inserting one row at a time - |
#18
| |||
| |||
|
|
You can certainly insert many rows in one go. |
#19
| ||||
| ||||
|
|
This is in correct. You can certinly insert many rows in one go. |
|
However, until you have committed, no other process can insert, so there is serialisation. Which may be utterly bad, or simply no issue. |
|
When it is an issue, IDENTITY is certainly worth considering. But where there are no concurrency issues in sight there is little reason to use IDENTITY, since there are a couple of usability problems with it - you see them on the newsgroups all the time. |
|
Tony Rogerson (tonyrogerson (AT) torver (DOT) net) writes: You cannot use BCP or BULK INSERT for the method you propose, the MAX(col) + 1; with that method you are limited to inserting one row at a time - This is in correct. You can certinly insert many rows in one go. However, until you have committed, no other process can insert, so there is serialisation. Which may be utterly bad, or simply no issue. When it is an issue, IDENTITY is certainly worth considering. But where there are no concurrency issues in sight there is little reason to use IDENTITY, since there are a couple of usability problems with it - you see them on the newsgroups all the time. -- Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) 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 SQL 2000: http://www.microsoft.com/sql/prodinf...ons/books.mspx |
#20
| |||
| |||
|
|
The fact that IDENTITY has to queue the rows in a multi-row insertion in a non-deterministic fashion has been a big problem for me. It means there is no hope of validation. |
|
see if that works. But I also need to play with INSERT INTO Foobar (foo_seq, ..) VALUES ( (SELECT COALESCE (MAX(Foobar.foo_seq), 0) + ROW_NUMBER() OVER (ORDER BY some_sequencing_columns)) FROM NewFoobar) ..); |
|
You can certainly insert many rows in one go. The fact that IDENTITY has to queue the rows in a multi-row insertion in a non-deterministic fashion has been a big problem for me. It means there is no hope of validation. I need to look at the Standard CREATE SEQUENCE statement in depth to see if that works. But I also need to play with INSERT INTO Foobar (foo_seq, ..) VALUES ( (SELECT COALESCE (MAX(Foobar.foo_seq), 0) + ROW_NUMBER() OVER (ORDER BY some_sequencing_columns)) FROM NewFoobar) ..); or worse |
![]() |
| Thread Tools | |
| Display Modes | |
| |