Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Creating a duplicate row

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 trigger
CREATE TRIGGER	dbo.trgPlaces
ON dbo.Places
AFTER DELETE
AS

SET NOCOUNT ON

IF 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)
END
GO
To make sure you always display the latest versions, use this view
CREATE VIEW dbo.vwLatestVersions
AS

WITH 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 cteSource
WHERE rn = 1
GO



Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
Go to Top of Page

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)
);
GO
ALTER TABLE dbo.Places
ADD DEFAULT (0)
FOR Validated
GO
CREATE VIEW dbo.vwPlaces
AS

-- Only display the latest version of validated rows
WITH 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,
Longitude
FROM cteSource
WHERE rn = 1
GO
CREATE TRIGGER dbo.trgUpdatePlaces
ON dbo.Places
INSTEAD OF UPDATE
AS

SET NOCOUNT ON;

-- Prevent UPDATE and make the new version an INSERT instead.
INSERT dbo.Places
(
Name,
Town,
Latitude,
Longitude
)
SELECT Name,
Town,
Latitude,
Longitude
FROM inserted
WHERE Name IS NOT NULL
AND Town IS NOT NULL
GO

-- 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
-- Cleanup
DROP VIEW dbo.vwPlaces
DROP TABLE dbo.Places
GO



Microsoft SQL Server MVP, MCT, MCSE, MCSA, MCP, MCITP, MCTS, MCDBA
Go to Top of Page

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.


Go to Top of Page
   

- Advertisement -