I have a very simple question about transactions. (in sql server 2000, but i guess it applies to general db. transactions).
tblPrimaryKey
PkId
-----
1
2
3
tblForeignKey
Id ForeignKey
---- -----
1 1
2 2
3 3
4 1
I have 2 tables, one referencing the other (tblForeingKey.ForeignKey references tblPrimaryKey.PkID). Now I have some logics that alters the tabel of the primary key, by deleting and reinserting a key.
After deleting the database would be ofcourse in an inconsistent state. I looked at on old script of mine where I first dropped the relationship and recreated it afterwards. But my question is this : I learned that a transaction is atomic, so inside of a transaction inconsistent state is allowed.
So I guess something like this should work:
BEGIN TRAN eg
DELETE tblPrimaryKey WHERE PkId = 3
INSERT INTO tblPrimaryKey SELECT 3
COMMIT TRAN eg
But this doesn't work. Can someone provide me with an example of a working transaction that applies this logic?
UPDATES :
Consistency This characteristic means that the database should be consistent before and after the transaction.
In no case can a partial transaction be committed to the database since that would leave the database in an inconsistent state.
Doesn't this imply that in the transaction inconsistency is possible?
UPDATE :
Some have asked me why I didn't use an update in this case. Kind of complicated but I give it a go : the sql needed was part of a publication script that build tables from views, and then updated those tables. Since the views contained the publicationmodel, alterations of the view were made there, and only there. The rest of the script could not rely on column names to do the update.
Ofcourse I could query for those columnnames, but it seem like a hassle at the time, so I choosed not to, and instead drop constraints an rebuild them. Now I must admit I wasn't feeling comfortable myself with that solution, so now I use indeed an update instead. I wrote a sproc to do that, if anyone nows an other solution, please let me know.
CREATE PROC usp_SyncRecords
(
@tableName1 as nvarchar(255),
@tableName2 as nvarchar(255),
@joinClause as nvarchar(255),
@whereClause as nvarchar(1000)
)
-- this proc updates all fields in table 1 that have corresponding names
-- in table2 to the value of the field in table2.
AS
BEGIN
DECLARE @sqlClause nvarchar(4000)
DECLARE @curFieldName nvarchar(255)
DECLARE @sqlColumnCursorClause nvarchar(1000)
SET @sqlClause = 'UPDATE [' + @tableName1 + '] SET '
-- get FieldNames for second table
SET @sqlColumnCursorClause =
'DECLARE cur CURSOR FAST_FORWARD FOR SELECT name FROM syscolumns ' +
'WHERE id=' + CAST(object_id(@tableName2) as nvarchar(50))
EXEC sp_executeSql @sqlColumnCursorClause
OPEN cur
-- compose sqlClause using fieldnames
FETCH NEXT FROM CUR INTO @curFieldName
WHILE @@fetch_status <> -1
BEGIN
SET @sqlClause = @sqlClause + @curFieldName + '=' +
@tableName2 + '.' + @curFieldName + ','
FETCH NEXT FROM CUR INTO @curFieldName
END
CLOSE cur
DEALLOCATE cur
-- drop last comma
SET @sqlClause = LEFT(@sqlClause,LEN(@sqlClause) -1)
-- adding from/join/where clauses
SET @sqlClause = @sqlClause + ' FROM [' + @tableName1 + '] INNER JOIN [' + @tableName2 + '] '
+ 'ON ' + @joinClause + ' WHERE ' + @whereClause
EXEC sp_executeSQL @sqlClause
END