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
 SQL Server 2000 Forums
 Transact-SQL (2000)
 UPSERT and Log

Author  Topic 

Billkamm
Posting Yak Master

124 Posts

Posted - 2006-01-27 : 11:51:07
This post is related to my previous post:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60825

I have a list of documents and attributes associated with them that are generated dynamically from an ASP.Net page.

I need to either update the changes to those documents or insert the new documents into a table and then log indivudally the changes to any of those. Here is my plan let me know if you believe this is a good way of going about this or if you can think of a better way.


  • I will loop through all the controls on my website and dynamically generate an INSERT INTO statement and place the results into a temporary table (is there a way I can truely make this a temporary table via ADO.Net code or do I have to use presistent "temp" table?)

  • Run a query and place all values that will be updated into another temp table

  • Run a query and place all values that will be inserted into the same temp table as those being updated (I will use a flag to determine if it is an update or insert)

  • Run the update query

  • Run the insert query

  • Use a cursor to loop through that second temp able and one by one insert rows into the log table


Kristen
Test

22859 Posts

Posted - 2006-01-28 : 02:45:23
For the last step can you use a trigger?

Kristen
Go to Top of Page

Billkamm
Posting Yak Master

124 Posts

Posted - 2006-01-30 : 08:25:49
Well there is additional data I need to put in the audit table such as the user perfroming the action and I don't know of a way to "pass" information to a trigger
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2006-01-30 : 08:38:04
quote:
Originally posted by Billkamm

Well there is additional data I need to put in the audit table such as the user perfroming the action and I don't know of a way to "pass" information to a trigger


use system_user

----------------------------------
'KH'


Go to Top of Page

Billkamm
Posting Yak Master

124 Posts

Posted - 2006-01-30 : 08:57:46
It isn't that type of a user. It is a user stored in a table tblUsers.
Go to Top of Page

Billkamm
Posting Yak Master

124 Posts

Posted - 2006-01-30 : 12:47:53
I have found a way. I simply turn my UPDATE and INSERT statements into SELECT statements and wrap them within an INSERT INTO tblUsageLog statement.

At least I'm assuming this will work. I'll post the code if it does.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2006-01-30 : 14:38:49
It sounds OK, but its restricted to "application code" that bothers to update the audit trail, which leaves it a bit weak when considering hackers, ad hoc DBA scripted updates, and so on.

We put the User ID who made the update in every record, so that makes it easy for our Audit Trail Triggers to "attribute" the change.

(We have Create/Update Date as well as Create/Update User columns in pretty much every table)

Kristen
Go to Top of Page

Billkamm
Posting Yak Master

124 Posts

Posted - 2006-01-30 : 14:50:26
ok I'm having a problem with my code (explanation below code in bold)


-- Will update or insert document information into tblApplicationDocuments
CREATE PROCEDURE dbo.usp_UpdateAppDocs
(
-- The user ID is required, so it can be added to the usage log
@pkUserID int,

-- The application number
@AppNumber int,

-- The date and time the status changed
@DateStatusChanged datetime
)
AS

SET NOCOUNT ON

-- Log the updated documents
INSERT INTO tblUsageLog
(
fkApplicationNumber,
DateTimeOfAction,
fkUserID,
Description
)
SELECT
@AppNumber,
@DateStatusChanged,
@pkUserID,
'Changed ' + logInfo.DocumentName + ' from ' + logInfo.OldDocumentStatus + ' to ' + NewDocumentStatus
FROM
(
SELECT
DocumentName,
DocumentStatus OldDocumentStatus,
(
SELECT DocumentStatus
FROM tlkpDocumentStatuses
WHERE pkDocumentStatusID = S.fkDocOrTaskStatus
) NewDocumentStatus
-- Alias D is for "Destination", Alias S is for "Source"
FROM qryApplicationDocuments AS D JOIN #temptblApplicationDocuments AS S
ON D.fkApplicationNumber = S.fkIdNumber
AND D.fkDocumentID = S.fkDocOrTaskID
WHERE
(
(D.fkDocumentStatus <> S.fkDocOrTaskStatus
OR (D.fkDocumentStatus IS NULL AND S.fkDocOrTaskStatus IS NOT NULL)
OR (D.fkDocumentStatus IS NOT NULL AND S.fkDocOrTaskStatus IS NULL))
AND fkApplicationNumber = @AppNumber
)
) logInfo


When D.fkDocumentStatus IS NULL and S.fkDocOrTaskStatus IS NOT NULL it does not insert a new record tblUsageLog.

It works perfectly fine for where there are no NULL values, but the values are different. Any suggestions?


tblApplicationDocuments:

CREATE TABLE [dbo].[tblApplicationDocuments] (
[pkApplicationDocumentID] [bigint] IDENTITY (1, 1) NOT NULL ,
[fkApplicationNumber] [int] NOT NULL ,
[fkDocumentID] [int] NOT NULL ,
[DateReceived] [datetime] NULL ,
[fkDocumentStatus] [int] NULL
) ON [PRIMARY]


qryApplicationDocuments and #temptblApplicationDocuments pull off the same basic structure as above except qryApplicationDocuments pulls in some additional plain text based on foreign keys in addition to every field tblApplicationDocuments has and #temptblApplicationDocuments has some fields renamed.

tblUsageLog:

CREATE TABLE [dbo].[tblUsageLog] (
[pkUsageLogID] [int] IDENTITY (1, 1) NOT NULL ,
[fkApplicationNumber] [int] NULL ,
[fkBrokerID] [int] NULL ,
[DateTimeOfAction] [datetime] NOT NULL ,
[fkUserID] [int] NOT NULL ,
[Description] [varchar] (500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
Go to Top of Page
   

- Advertisement -