|
database
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Default Values for a Columncolumn (PartID) when the row is inserted. This value may be updated later, but at the point where the row is created, I want the values to be the same. The PartID column is an Identity column so I don't know the value in advance. As far as I understand it, you can't have a calculated value as the default value for a column; can somebody confirm this? So I have thought of two alternatives: 1) Create a trigger that takes the identity value for PartID and updates the EquivNo column [How do I know what the inserted PartID is within the trigger?] 2) The stored procedure inserts the row on the first pass, and uses Scope_Identy() to update the EquivNo in an update statement. I was just wondering about the relative merits of these two solutions. And are there any better alternatives? Thanks in advance Chris An advantage of using 1 is that the modifications are performed in the same transaction. The trigger
code is very straight forward: USE tempdb drop table t GO create table t(c1 int identity primary key, c2 int NULL) GO CREATE TRIGGER tr ON T FOR INSERT AS UPDATE t SET c2 = c1 WHERE EXISTS ( SELECT * FROM inserted AS i WHERE i.c1 = t.c1 ) GO insert into t(c2) VALUES(NULL) insert into t(c2) VALUES(NULL) insert into t(c2) VALUES(NULL) insert into t(c2) VALUES(NULL) SELECT * FROM t -- Show quoteTibor Karaszi, SQL Server MVP http://www.karaszi.com/sqlserver/default.asp http://www.solidqualitylearning.com/ Blog: http://solidqualitylearning.com/blogs/tibor/ "CJM" <cjmnews04@newsgroup.nospam> wrote in message news:%23UkDUPWWGHA.3448@TK2MSFTNGP03.phx.gbl... >I have table where I want one column (EquivNo) to default to the primary key column (PartID) when >the row is inserted. This value may be updated later, but at the point where the row is created, I >want the values to be the same. The PartID column is an Identity column so I don't know the value >in advance. > > As far as I understand it, you can't have a calculated value as the default value for a column; > can somebody confirm this? > > So I have thought of two alternatives: > 1) Create a trigger that takes the identity value for PartID and updates the EquivNo column > > [How do I know what the inserted PartID is within the trigger?] > > 2) The stored procedure inserts the row on the first pass, and uses Scope_Identy() to update the > EquivNo in an update statement. > > I was just wondering about the relative merits of these two solutions. And are there any better > alternatives? > > Thanks in advance > > Chris > Tibor
> An advantage of using 1 is that the modifications are performed in the Just keep thinking if the user inserts a new row (one transaction) , the > same transaction. The trigger code is very straight forward: trigger is fired and open another transaction, am I right? If the trigger fails that an identity peroperty is already in the table , so actually in my opinion that using a stored procedure will be more useful in terms of performans as well as more secure. CREATE PROC myproc AS DECLARE @idnt INT BEGIN TRAN INSERT INTO T1 VALUES (.....) SELECT @idnt =SCOPE_IDENTITY() INSERT INTO T2 SELECT @idnt --Error handler here COMMIT Show quote "Tibor Karaszi" <tibor_please.no.email_kara***@hotmail.nomail.com> wrote in message news:%23C2r4bWWGHA.5096@TK2MSFTNGP03.phx.gbl... > An advantage of using 1 is that the modifications are performed in the > same transaction. The trigger code is very straight forward: > > USE tempdb > > drop table t > GO > create table t(c1 int identity primary key, c2 int NULL) > GO > CREATE TRIGGER tr ON T FOR INSERT > AS > UPDATE t SET c2 = c1 > WHERE EXISTS > ( > SELECT * > FROM inserted AS i > WHERE i.c1 = t.c1 > ) > GO > > insert into t(c2) VALUES(NULL) > insert into t(c2) VALUES(NULL) > insert into t(c2) VALUES(NULL) > insert into t(c2) VALUES(NULL) > > SELECT * FROM t > > > -- > Tibor Karaszi, SQL Server MVP > http://www.karaszi.com/sqlserver/default.asp > http://www.solidqualitylearning.com/ > Blog: http://solidqualitylearning.com/blogs/tibor/ > > > "CJM" <cjmnews04@newsgroup.nospam> wrote in message > news:%23UkDUPWWGHA.3448@TK2MSFTNGP03.phx.gbl... >>I have table where I want one column (EquivNo) to default to the primary >>key column (PartID) when the row is inserted. This value may be updated >>later, but at the point where the row is created, I want the values to be >>the same. The PartID column is an Identity column so I don't know the >>value in advance. >> >> As far as I understand it, you can't have a calculated value as the >> default value for a column; can somebody confirm this? >> >> So I have thought of two alternatives: >> 1) Create a trigger that takes the identity value for PartID and updates >> the EquivNo column >> >> [How do I know what the inserted PartID is within the trigger?] >> >> 2) The stored procedure inserts the row on the first pass, and uses >> Scope_Identy() to update the EquivNo in an update statement. >> >> I was just wondering about the relative merits of these two solutions. >> And are there any better alternatives? >> >> Thanks in advance >> >> Chris >> > > Just keep thinking if the user inserts a new row (one transaction) , the No, the code in a trigger is in the same transaction as the statement that fired the trigger.> trigger is fired and open another transaction, am I right? -- Show quoteTibor Karaszi, SQL Server MVP http://www.karaszi.com/sqlserver/default.asp http://www.solidqualitylearning.com/ Blog: http://solidqualitylearning.com/blogs/tibor/ "Uri Dimant" <u***@iscar.co.il> wrote in message news:OxFvq8WWGHA.3800@TK2MSFTNGP03.phx.gbl... > Tibor >> An advantage of using 1 is that the modifications are performed in the >> same transaction. The trigger code is very straight forward: > > Just keep thinking if the user inserts a new row (one transaction) , the > trigger is fired and open another transaction, am I right? > If the trigger fails that an identity peroperty is already in the table , so > actually in my opinion that using > a stored procedure will be more useful in terms of performans as well as > more secure. > > > CREATE PROC myproc > AS > DECLARE @idnt INT > BEGIN TRAN > > INSERT INTO T1 VALUES (.....) > SELECT @idnt =SCOPE_IDENTITY() > INSERT INTO T2 SELECT @idnt > --Error handler here > COMMIT > > > "Tibor Karaszi" <tibor_please.no.email_kara***@hotmail.nomail.com> wrote in > message news:%23C2r4bWWGHA.5096@TK2MSFTNGP03.phx.gbl... >> An advantage of using 1 is that the modifications are performed in the >> same transaction. The trigger code is very straight forward: >> >> USE tempdb >> >> drop table t >> GO >> create table t(c1 int identity primary key, c2 int NULL) >> GO >> CREATE TRIGGER tr ON T FOR INSERT >> AS >> UPDATE t SET c2 = c1 >> WHERE EXISTS >> ( >> SELECT * >> FROM inserted AS i >> WHERE i.c1 = t.c1 >> ) >> GO >> >> insert into t(c2) VALUES(NULL) >> insert into t(c2) VALUES(NULL) >> insert into t(c2) VALUES(NULL) >> insert into t(c2) VALUES(NULL) >> >> SELECT * FROM t >> >> >> -- >> Tibor Karaszi, SQL Server MVP >> http://www.karaszi.com/sqlserver/default.asp >> http://www.solidqualitylearning.com/ >> Blog: http://solidqualitylearning.com/blogs/tibor/ >> >> >> "CJM" <cjmnews04@newsgroup.nospam> wrote in message >> news:%23UkDUPWWGHA.3448@TK2MSFTNGP03.phx.gbl... >>>I have table where I want one column (EquivNo) to default to the primary >>>key column (PartID) when the row is inserted. This value may be updated >>>later, but at the point where the row is created, I want the values to be >>>the same. The PartID column is an Identity column so I don't know the >>>value in advance. >>> >>> As far as I understand it, you can't have a calculated value as the >>> default value for a column; can somebody confirm this? >>> >>> So I have thought of two alternatives: >>> 1) Create a trigger that takes the identity value for PartID and updates >>> the EquivNo column >>> >>> [How do I know what the inserted PartID is within the trigger?] >>> >>> 2) The stored procedure inserts the row on the first pass, and uses >>> Scope_Identy() to update the EquivNo in an update statement. >>> >>> I was just wondering about the relative merits of these two solutions. >>> And are there any better alternatives? >>> >>> Thanks in advance >>> >>> Chris >>> >> > > Surely the transaction issue is a red herring? That is, we can explicitly
define what is and isn't included in the transaction (Begin/Commit/Rollback) anyway. > Surely the transaction issue is a red herring? That is, we can explicitly define what is and isn't Yes, of course we can. My point (perhaps not explicit enough) was that the transaction handling will > included in the transaction (Begin/Commit/Rollback) anyway. be transparent for those who does INSERTs into the table. -- Show quoteTibor Karaszi, SQL Server MVP http://www.karaszi.com/sqlserver/default.asp http://www.solidqualitylearning.com/ Blog: http://solidqualitylearning.com/blogs/tibor/ "CJM" <cjmnews04@newsgroup.nospam> wrote in message news:%23lbLUbXWGHA.924@TK2MSFTNGP03.phx.gbl... > Surely the transaction issue is a red herring? That is, we can explicitly define what is and isn't > included in the transaction (Begin/Commit/Rollback) anyway. > CJM wrote:
Show quote > I have table where I want one column (EquivNo) to default to the primary key Is EquivNo a self-referencing foreign key? (please post DDL, then we> column (PartID) when the row is inserted. This value may be updated later, > but at the point where the row is created, I want the values to be the same. > The PartID column is an Identity column so I don't know the value in > advance. > > As far as I understand it, you can't have a calculated value as the default > value for a column; can somebody confirm this? > > So I have thought of two alternatives: > 1) Create a trigger that takes the identity value for PartID and updates the > EquivNo column > > [How do I know what the inserted PartID is within the trigger?] > > 2) The stored procedure inserts the row on the first pass, and uses > Scope_Identy() to update the EquivNo in an update statement. > > I was just wondering about the relative merits of these two solutions. And > are there any better alternatives? > > Thanks in advance > > Chris won't have to guess). I'm of the opinion that IDENTITY isn't a good choice to use as a foreign key in the same table. Your problem is just one of one of the reasons why. If EquivNo is not a key then I'm not sure why you'd want it to be the same as the PartID. It's a bad idea to expose IDENTITY columns to users. From the business perspective it shouldn't matter what value is assigned to PartID and therefore it shouldn't matter whether it's the same as EquivNo. I think that your real problem is that you need a more convenient alternative method to generate an incrementing key for EquivNo. See the following article for suggestions: http://www.sqlmag.com/Articles/ArticleID/48165/48165.html -- David Portas, SQL Server MVP Whenever possible please post enough code to reproduce your problem. Including CREATE TABLE and INSERT statements usually helps. State what version of SQL Server you are using and specify the content of any error messages. SQL Server Books Online: http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx -- "David Portas" <REMOVE_BEFORE_REPLYING_dpor***@acm.org> wrote in message I think you hit the nail on the head here... I want EquivNo to be assigned a news:1144320223.938968.220540@g10g2000cwb.googlegroups.com... >I think that your real problem is that you need a more > convenient alternative method to generate an incrementing key for > EquivNo. new, unique value when the row is inserted, but at a later point in time, it may change - therefore an identity field wouldn't be appropriate. I'm proposing using a the PartID value because it is an arbitrary-but-unique value. But I'm open to any other ideas. >See the following article for suggestions: I'm afraid that this link is subscription-only.> http://www.sqlmag.com/Articles/ArticleID/48165/48165.html > Thanks Chris CJM
Second one seems to be good for you. Show quote "CJM" <cjmnews04@newsgroup.nospam> wrote in message news:%23UkDUPWWGHA.3448@TK2MSFTNGP03.phx.gbl... >I have table where I want one column (EquivNo) to default to the primary >key column (PartID) when the row is inserted. This value may be updated >later, but at the point where the row is created, I want the values to be >the same. The PartID column is an Identity column so I don't know the value >in advance. > > As far as I understand it, you can't have a calculated value as the > default value for a column; can somebody confirm this? > > So I have thought of two alternatives: > 1) Create a trigger that takes the identity value for PartID and updates > the EquivNo column > > [How do I know what the inserted PartID is within the trigger?] > > 2) The stored procedure inserts the row on the first pass, and uses > Scope_Identy() to update the EquivNo in an update statement. > > I was just wondering about the relative merits of these two solutions. And > are there any better alternatives? > > Thanks in advance > > Chris > "Uri Dimant" <u***@iscar.co.il> wrote in message I'm erring this way, if only because it's a simple and uncomplicated news:%23E1lfUWWGHA.3800@TK2MSFTNGP03.phx.gbl... > CJM > Second one seems to be good for you. > > solution. Did you look at the trigger code I posted? What part of that code did you find complicated? I'm not
trying to defend my proposal, I just want to make sure you see the simplicity of the trigger alternative. Oh, and I fully agree with David's point regarding IDENTITY should be complemented with a natural key and identity not be exposed to users, btw. -- Show quoteTibor Karaszi, SQL Server MVP http://www.karaszi.com/sqlserver/default.asp http://www.solidqualitylearning.com/ Blog: http://solidqualitylearning.com/blogs/tibor/ "CJM" <cjmnews04@newsgroup.nospam> wrote in message news:u$0KGgXWGHA.1348@TK2MSFTNGP05.phx.gbl... > > "Uri Dimant" <u***@iscar.co.il> wrote in message news:%23E1lfUWWGHA.3800@TK2MSFTNGP03.phx.gbl... >> CJM >> Second one seems to be good for you. >> >> > > I'm erring this way, if only because it's a simple and uncomplicated solution. > "Tibor Karaszi" <tibor_please.no.email_kara***@hotmail.nomail.com> wrote in lol. Yes I did... It's just that I haven't used triggers much in the past. message news:eOoNfjXWGHA.3440@TK2MSFTNGP02.phx.gbl... > Did you look at the trigger code I posted? What part of that code did you > find complicated? I'm not trying to defend my proposal, I just want to > make sure you see the simplicity of the trigger alternative. > So I'm debating whether to use this as trigger-practice, or to stick with what I know... Snippet: Alter TRIGGER SetEquivNo ON PartMaster For INSERT AS BEGIN SET NOCOUNT ON; UPDATE PartMaster P SET P.EquivNo = i.PartID WHERE EXISTS ( SELECT I.PartID FROM Inserted AS I WHERE I.PartID = P.PartID ) END At the moment, it reckons there is a problem after the 'Update PartMaster P' line - Incorrect Syntax! What have I missed? > Oh, and I fully agree with David's point regarding IDENTITY should be This field is not exposed to the user. But even if it was, there is no > complemented with a natural key and identity not be exposed to users, btw. > natural key to choose... This column is used to link several PartNos together to show that they are effectively equivalent - Parts with the same EquivNo are 'equivalent'. The user doesnt see it or need to know about it. I *could* have created another table to record equivalences, such that EquivNo *would* have been a foreign key to the 'Equivalences' table, but given the limited use of this column, there would have been no other benefit to this method. Cheers Chris > At the moment, it reckons there is a problem after the 'Update PartMaster P' line - Incorrect You cannot define a table alias in an UPDATE statement (skip the " P" on the first line of the > Syntax! What have I missed? UPDATE). See my original trigger I posted, I didn't define a table alias in the UPDATE for this particular reason... :-) -- Show quoteTibor Karaszi, SQL Server MVP http://www.karaszi.com/sqlserver/default.asp http://www.solidqualitylearning.com/ Blog: http://solidqualitylearning.com/blogs/tibor/ "CJM" <cjmnews04@newsgroup.nospam> wrote in message news:ugPszwYWGHA.5096@TK2MSFTNGP03.phx.gbl... > > "Tibor Karaszi" <tibor_please.no.email_kara***@hotmail.nomail.com> wrote in message > news:eOoNfjXWGHA.3440@TK2MSFTNGP02.phx.gbl... >> Did you look at the trigger code I posted? What part of that code did you find complicated? I'm >> not trying to defend my proposal, I just want to make sure you see the simplicity of the trigger >> alternative. >> > > lol. Yes I did... It's just that I haven't used triggers much in the past. So I'm debating whether > to use this as trigger-practice, or to stick with what I know... > > Snippet: > > Alter TRIGGER SetEquivNo > ON PartMaster > For INSERT > AS > BEGIN > > SET NOCOUNT ON; > > UPDATE PartMaster P > SET P.EquivNo = i.PartID > WHERE EXISTS > ( > SELECT I.PartID > FROM Inserted AS I > WHERE I.PartID = P.PartID > ) > END > > > At the moment, it reckons there is a problem after the 'Update PartMaster P' line - Incorrect > Syntax! What have I missed? > >> Oh, and I fully agree with David's point regarding IDENTITY should be complemented with a natural >> key and identity not be exposed to users, btw. >> > > This field is not exposed to the user. But even if it was, there is no natural key to choose... > > This column is used to link several PartNos together to show that they are effectively > equivalent - Parts with the same EquivNo are 'equivalent'. The user doesnt see it or need to know > about it. > > I *could* have created another table to record equivalences, such that EquivNo *would* have been a > foreign key to the 'Equivalences' table, but given the limited use of this column, there would > have been no other benefit to this method. > > Cheers > > Chris > |
|||||||||||||||||||||||