Author |
Topic |
sqlconfused
Yak 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 |
|
SwePeso
Patron 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 triggerCREATE 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) ENDGO To 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 |
|
|
SwePeso
Patron 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.PlacesGO Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA |
|
|
sqlconfused
Yak 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. |
|
|
|
|
|