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 2008 Forums
 Transact-SQL (2008)
 Need help with the Query.

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]
GO

CREATE 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);
GO

Result want:
LoanNum URL
------- ---
10001 /Doc/10001/CC/Test/5532/02/08/2011
10002 /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 URL
both function can be obtained from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033

something like this . .

SELECT LoanNum = dbo.fnParseString(-3, '/', ltrim(Data)), URL = ltrim(Data)
FROM dbo.fnParseList(';', @URL)



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

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]

Go to Top of Page

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 and
get the results showing with 4 test cases below. I wonder if you can help to incorporate into MERGE statement
and 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]
GO

CREATE 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/2011
1 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 ZYZ
1 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]
GO

CREATE PROCedure [dbo].[spWorkQ_DocumentAttachmentUpdate]
(
@DocumentActionId INT
,@LoginId VARCHAR(50)
,@URL VARCHAR(8000)
)
AS
/**********************************************************************************************
** Modifications:
** ----------------------------------
** Date: Author: Reasons:
** ------------+-----------------------------------------------------------------------
**
**
*********************************************************************************************/
SET nocount ON

DECLARE @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 = @LoanNum

END TRY



BEGIN CATCH

SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE()

RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState)

END CATCH
SET nocount OFF
GO

-------------------------------------------------------------------

-- 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]
GO
CREATE FUNCTION [dbo].[fn_tblDelimiter] (@list varchar(8000),@Delimeter char(1))
RETURNS @tblItem TABLE(Item varchar(50))
AS
BEGIN

DECLARE @Item varchar(50)
DECLARE @StartPos int, @Length int
WHILE 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)
END

return
END
GO


quote:
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 URL
both function can be obtained from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033

something like this . .

SELECT LoanNum = dbo.fnParseString(-3, '/', ltrim(Data)), URL = ltrim(Data)
FROM dbo.fnParseList(';', @URL)



KH
[spoiler]Time is always against us[/spoiler]



Go to Top of Page
   

- Advertisement -