| 
                
                    | 
                            
                                | Author | Topic |  
                                    | sqlconfusedYak Posting Veteran
 
 
                                        50 Posts | 
                                            
                                            |  Posted - 2013-09-17 : 12:47:58 
 |  
                                            | Hi..I have a table that I'll call 'places'. This is a table of places to visit and might look like this:id (autoincrement), name, town, latitude, longitude, etc1, etc2, description==========================================================1, My barn, Toronto, 43.44, -79,443, y, n, "Country barn"2, run down house, 46.4432, -79.4322, y, y, "this is an old house that seems to have been forgotten"4, parking lot, 45.4322, -80,4333, n, n, "An vacant parking lot, overrun with grass"I'm trying to implement a 'revert' feature sort of like Wikipedia's (Undo) where if someone vandalizes an entry in the table I can revert it. People can edit the description and latitude, longitude. The ID and name generally stay the same.I'd like to copy the entire row (about 20 columns in a single row, I didn't list them all) to a temporary table or new row. I think using a new row in the same table might not be a good idea because it would cause the autoincrement ID to increase and I plan to delete the temp row when done with it anyway. Don't want too many gaps in the ID field.Basically I want to have a script (I'll code it myself) that I can approve or disprove the changes to the row. If the changes are invalid (someone has put bad info in, erased the GPS fields, etc) then I just delete the temporary row and nothing changes.If it's a valid change then I'd have to do something like an UPDATE to update the original row with the info from the temp table.eg. OLD data from 'places'2, run down house, 46.4432, -79.4322, y, y, "this is an old house that seems to have been forgotten"NEW data put into 'places' via UPDATE command:2, run down house, 46.4342, -79.4222, y, y, "this is an old house that seems to have been forgotten. I have fixed the GPS data that was inauurate."So it's a matter of updating the old row and deleting the temp table afterwards. I'm not familiar with stored functions or routines in SQL. I use Server Management Studio but only for running queries and viewing the columns - I don't know how to store any routines in the database.All my code is done simply by sending strings to SQL from Active Server:sqlst = "insert into table <whatever>"Set objRs = objCmd.Execute(sqlst)So if it's possible to accomplish this just through executing a few  queries, great. Otherwise I might have to learn how to do a stored routine in SQL.Any help would be appreciated  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2013-09-17 : 13:18:19 
 |  
                                          | You don't need anything of that sort!Since you already have an IDENTITY column, you can use that as a "Version" indicator. If not happy with the latest version just delete the row, unless it is the "first" row version.To prevent deleting the "first row", use this trigger CREATE TRIGGER	dbo.trgPlacesON		dbo.PlacesAFTER		DELETEASSET NOCOUNT ONIF EXISTS	(			SELECT		*			FROM		deleted AS d			INNER JOIN	(						SELECT		MIN(ID) AS minID						FROM		dbo.Places						GROUP BY	Name,								Town					) AS w ON w.minID = d.ID		)	BEGIN		ROLLBACK TRAN		RAISERROR('You are not allowed to delete the first version.', 16, 1)	ENDGOTo make sure you always display the latest versions, use this viewCREATE VIEW dbo.vwLatestVersionsASWITH cteSource(ID, Name, Town, Latitude, Longitude, Etc1, Etc2, [Description], rn)AS (	SELECT	ID,		Name, 		Town, 		Latitude, 		Longitude, 		Etc1, 		Etc2, 		[Description],		ROW_NUMBER() OVER (PARTITION BY Name, Town ORDER BY ID DESC) AS rn	FROM	dbo.Places)SELECT	ID,	Name, 	Town, 	Latitude, 	Longitude, 	Etc1, 	Etc2, 	[Description]FROM	cteSourceWHERE	rn = 1GO Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | SwePesoPatron Saint of Lost Yaks
 
 
                                    30421 Posts | 
                                        
                                          |  Posted - 2013-09-17 : 13:37:46 
 |  
                                          | However, this is probably how I would do it. CREATE TABLE	dbo.Places		(			Validated TINYINT NOT NULL,			ID INT IDENTITY(1, 1) CONSTRAINT PK_Places PRIMARY KEY CLUSTERED,			Name NVARCHAR(100) NOT NULL,			Town NVARCHAR(100) NOT NULL,			Latitude DECIMAL(9, 6),			Longitude DECIMAL(9, 6)		);GOALTER TABLE	dbo.PlacesADD		DEFAULT (0)FOR		ValidatedGOCREATE VIEW	dbo.vwPlacesAS-- Only display the latest version of validated rowsWITH cteSource(ID, Name, Town, Latitude, Longitude, rn)AS (	SELECT	ID, 		Name, 		Town, 		Latitude, 		Longitude,		ROW_NUMBER() OVER (PARTITION BY Name, Town ORDER BY ID DESC) AS rn	FROM	dbo.Places	WHERE	Validated = 1)SELECT	ID, 	Name, 	Town, 	Latitude, 	LongitudeFROM	cteSourceWHERE	rn = 1GOCREATE TRIGGER	dbo.trgUpdatePlacesON		dbo.PlacesINSTEAD OF	UPDATEASSET NOCOUNT ON;-- Prevent UPDATE and make the new version an INSERT instead.INSERT	dbo.Places	(		Name,		Town,		Latitude,		Longitude	)SELECT	Name,	Town,	Latitude,	LongitudeFROM	insertedWHERE	Name IS NOT NULL	AND Town IS NOT NULLGO-- Test!SELECT * FROM dbo.Places;INSERT dbo.Places(Name, Town) VALUES ('Petersplatsen', 'Bjuv');SELECT * FROM dbo.Places;INSERT dbo.Places(Name, Town, Latitude) VALUES ('Petersplatsen', 'Bjuv', 12);SELECT * FROM dbo.Places;UPDATE dbo.Places SET Latitude=  12.56 WHERE ID = 2;SELECT * FROM dbo.Places;GO-- CleanupDROP VIEW dbo.vwPlacesDROP TABLE dbo.PlacesGOMicrosoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
 |  
                                          |  |  |  
                                    | sqlconfusedYak Posting Veteran
 
 
                                    50 Posts | 
                                        
                                          |  Posted - 2013-09-17 : 13:55:01 
 |  
                                          | Thank you for the reply. It's going to take me a while to digest all of that information and try to figure out what it is doing. It's a little overwhelming.Also I use straightforward "select * from places where id = xxxx" to pull up the information. So a duplicate location would have a different id of course, and my select statement would always reference the first instance even if I had more than one row to choose from. |  
                                          |  |  |  
                                |  |  |  |