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.
| Author |
Topic |
|
NguyenL71
Posting Yak Master
228 Posts |
Posted - 2011-02-09 : 12:49:47
|
| [code]I need to parse out the URL data and delete duplicate values and wonder if you could help. I have the business rule showing below.I try to find a function to parse the data after ;. I am using SQL 2008.Any help would greatly appreciate.IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DocumentAttachment]') AND type in (N'U'))DROP TABLE [dbo].[Test]GOCREATE TABLE [dbo].[Test]( [DocumentActionId] [int] NOT NULL, [LoanNum] [varchar](10) NULL, [InsertDt] [datetime] NOT NULL, [InsertBy] [varchar](50) NOT NULL, [URL] [varchar](8000) NULL, CONSTRAINT [XPKTest] PRIMARY KEY CLUSTERED ( [DocumentActionId] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]GO INSERT Test (DocumentActionId, LoanNum, InsertDt, InsertBy, URL) VALUES (1, '10001', '2011-02-08 15:36:06.937', 'User1', '/Doc/10001/CC/Test/5532/02/08/2011') go SELECT * FROM Test GO----------------------------------------------------------------------------------Business rules: 1. Get only unique values after semi-colon ';' and insert into the table. 2. If the value is same in the table then don't update InsertDt or InsertBy (no duplicate data URL).DECLARE @LoanNum VARCHAR(10), @DocumentActionId INT = 1, @LoginId VARCHAR(50) = 'User1', @URL VARCHAR(8000) = ('/Doc/10001/CC/Test/5532/02/08/2011; /Doc/10001/CC/Test/5532/02/08/2011;/Doc/10002/CC/Test/8964/02/08/2011/Title;/Doc/10001/CC/Test/5532/02/08/2011') SELECT @LoanNum = '10001 --@DocumentActionId = DocumentActionId --FROM DocumentAttachment --WHERE DocumentActionId = @DocumentActionId --SELECT @DocumentActionId AS 'DocumentActionId', @LoanNum AS 'LoanNum', @LoginId AS '@LoginId', @URL AS 'URL' MERGE INTO Test AS t USING (VALUES ( @DocumentActionId, @LoanNum, @LoginId, @URL)) AS s (DocumentActionId, LoanNum, InsertBy, URL) ON t.DocumentActionId = s.DocumentActionId AND t.LoanNum = s.LoanNum WHEN MATCHED AND (t.URL <> s.URL) THEN UPDATE SET URL = s.URL, InsertDt = GETDATE(), InsertBy = s.InsertBy; WHEN NOT MATCHED BY TARGET THEN INSERT (DocumentActionId, LoanNum, InsertBy, InsertDt, URL) VALUES (s.DocumentActionId, s.LoanNum, s.InsertBy, CURRENT_TIMESTAMP, s.URL); GOResult want:LoanNum URL------- ---10001 /Doc/10001/CC/Test/5532/02/08/201110002 /Doc/10002/CC/Test/8964/02/08/2011/Title[/code] |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2011-02-09 : 21:48:29
|
you can use fnParseList() to split the @URL into rows and possibly fnParseString() to extract the LoanNum 10001, 10002 from the URLboth function can be obtained from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033something like this . .SELECT LoanNum = dbo.fnParseString(-3, '/', ltrim(Data)), URL = ltrim(Data)FROM dbo.fnParseList(';', @URL) KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2011-02-09 : 21:50:39
|
Just noticed that the column DocumentActionId is the PK column. In your current query, it is hardcoded with value 1 ? You will have insert problem with this. KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
NguyenL71
Posting Yak Master
228 Posts |
Posted - 2011-02-10 : 11:57:27
|
Hi,The SP below is working but I wonder If there is a better way to write this Without using the #Temp table andget the results showing with 4 test cases below. I wonder if you can help to incorporate into MERGE statementand get the same results.Thanks in advance.IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DocumentAttachment]') AND type in (N'U'))DROP TABLE [dbo].[DocumentAttachment]GOCREATE TABLE [dbo].[DocumentAttachment]( [DocumentActionId] [int] NOT NULL, [LoanNum] [varchar](10) NULL, [InsertDt] [datetime] NOT NULL, [InsertBy] [varchar](50) NOT NULL, [URL] [varchar](8000) NULL) GO INSERT DocumentAttachment (DocumentActionId, LoanNum, InsertDt, InsertBy, URL) VALUES (1, '10001', '2011-02-08 15:36:06.937', 'acruz', '/Doc/10001/CC/Test/5532/02/08/2011'); GO--Testing...EXECute dbo.spWorkQ_DocumentAttachmentUpdate @DocumentActionId = 1 ,@LoginId = 'Users' ,@URL = '/Doc/10001/CC/Test/5532/02/08/2011abcd;/Doc/10001/CC/Test/5532/02/08/2011 ZYZ' GO SELECT * FROM DocumentAttachment; GO --Case #1.-- Nothing has changed. @URL = '/Doc/10001/CC/Test/5532/02/08/2011;/Doc/10001/CC/Test/5532/02/08/2011'-- Result want:DocumentActionId LoanNum InsertDt InsertBy URL---------------- ---------- ----------------------- -------------------------------------------------- ----------------------------------1 10001 2011-02-08 15:36:06.937 acruz /Doc/10001/CC/Test/5532/02/08/2011 --Case #2. There is a changed in value ZYZ, insert a new row. @URL = '/Doc/10001/CC/Test/5532/02/08/2011;/Doc/10001/CC/Test/5532/02/08/2011 ZYZ'DocumentActionId LoanNum InsertDt InsertBy URL---------------- ---------- ----------------------- -------------------------------------------------- --------------------------------------1 10001 2011-02-08 15:36:06.937 acruz /Doc/10001/CC/Test/5532/02/08/20111 10001 2011-02-10 08:47:07.760 Users /Doc/10001/CC/Test/5532/02/08/2011 ZYZ -- Insert a new row.--Case #3. There is a changed in values and delete the old one in the table /Doc/10001/CC/Test/5532/02/08/2011.-- @URL = '/Doc/10001/CC/Test/5532/02/08/2011abc;/Doc/10001/CC/Test/5532/02/08/2011 ZYZ'DocumentActionId LoanNum InsertDt InsertBy URL---------------- ---------- ----------------------- -------------------------------------------------- ---------------------------------------1 10001 2011-02-10 08:47:07.760 Users /Doc/10001/CC/Test/5532/02/08/2011 ZYZ1 10001 2011-02-10 08:48:51.150 Users /Doc/10001/CC/Test/5532/02/08/2011abcd--Case #4. Delete all the values if URL passed in blank @URL = ''-- @URL = ''DocumentActionId LoanNum InsertDt InsertBy URL---------------- ---------- ----------------------- -------------------------------------------------- ---------------------------------------IF OBJECT_ID('[dbo].[spWorkQ_DocumentAttachmentUpdate]', 'p') IS NOT NULL DROP PROCedure [dbo].[spWorkQ_DocumentAttachmentUpdate]GOCREATE PROCedure [dbo].[spWorkQ_DocumentAttachmentUpdate]( @DocumentActionId INT ,@LoginId VARCHAR(50) ,@URL VARCHAR(8000))AS/************************************************************************************************ Modifications:** ----------------------------------** Date: Author: Reasons:** ------------+-----------------------------------------------------------------------*************************************************************************************************/SET nocount ONDECLARE @ErrorMessage VARCHAR(4000), @ErrorSeverity INT, @ErrorState INT, @LoanNum VARCHAR(10) SELECT @LoanNum = LoanNum FROM DocumentAttachment WHERE DocumentActionId = @DocumentActionId IF OBJECT_ID('Tempdb.dbo.#Temp', 'u') IS NOT NULL DROP TABLE #Temp CREATE TABLE #Temp ( DocumentActionId INT NULL, LoanNum VARCHAR(10) NULL, insertDt DATETIME NULL, InsertBy VARCHAR(50) NULL, URL VARCHAR(8000) NULL ) INSERT #Temp (DocumentActionId, LoanNum, InsertDt, InsertBy, URL) SELECT DISTINCT @DocumentActionId AS 'DocumentActionId', @LoanNum AS LoanNum, GETDATE() AS 'InsertDt', @LoginID AS InsertBy, item AS 'URL' FROM dbo.fn_tblDelimiter(@URL, ';') --SELECT * FROM #Temp BEGIN TRY MERGE INTO DocumentAttachment AS a USING #Temp AS b ON a.DocumentActionId = b.DocumentActionId AND a.LoanNum = b.LoanNum AND a.URL = b.URL WHEN MATCHED AND (a.URL <> b.URL) THEN UPDATE SET URL = b.URL, InsertDt = GETDATE(), InsertBy = b.InsertBy WHEN NOT MATCHED BY TARGET THEN INSERT (DocumentActionId, LoanNum, InsertBy, InsertDt, URL) VALUES (b.DocumentActionId, b.LoanNum, b.InsertBy, B.InsertDt, b.URL); DELETE a FROM DocumentAttachment AS a WHERE NOT EXISTS (SELECT 1 FROM #Temp AS b WHERE a.DocumentActionId = b.DocumentActionId AND a.LoanNum = b.LoanNum AND a.url = b.URL) AND a.DocumentActionId = @DocumentActionId AND a.LoanNum = @LoanNumEND TRYBEGIN CATCH SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE() RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState)END CATCHSET nocount OFFGO--------------------------------------------------------------------- create a function.IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_tblDelimiter]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))DROP FUNCTION [dbo].[fn_tblDelimiter]GOCREATE FUNCTION [dbo].[fn_tblDelimiter] (@list varchar(8000),@Delimeter char(1))RETURNS @tblItem TABLE(Item varchar(50))ASBEGINDECLARE @Item varchar(50)DECLARE @StartPos int, @Length intWHILE LEN(@list) > 0 BEGIN SET @StartPos = CHARINDEX(@Delimeter, @list) IF @StartPos < 0 SET @StartPos = 0 SET @Length = LEN(@list) - @StartPos - 1 IF @Length < 0 SET @Length = 0 IF @StartPos > 0 BEGIN SET @Item = SUBSTRING(@list, 1, @StartPos - 1) SET @list = SUBSTRING(@list, @StartPos + 1, LEN(@list) - @StartPos) END ELSE BEGIN SET @Item = @list SET @list = '' END INSERT @tblItem (Item) VALUES(@Item)ENDreturnENDGOquote: Originally posted by khtan you can use fnParseList() to split the @URL into rows and possibly fnParseString() to extract the LoanNum 10001, 10002 from the URLboth function can be obtained from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033something like this . .SELECT LoanNum = dbo.fnParseString(-3, '/', ltrim(Data)), URL = ltrim(Data)FROM dbo.fnParseList(';', @URL) KH[spoiler]Time is always against us[/spoiler]
|
 |
|
|
|
|
|
|
|