I have a Table name lines which has BillId (int) and LineReference (Varchar(100) as two columns. Each billid has LineReference value. However, value in the LineReference might n
1) On medium or long term I would like to normalize this database in order to avoid such mistakes: storing list of values within string/VARCHAR columns. For example, I would use following many to many table:
CREATE TABLE dbo.BillItem (
ID INT IDENTITY(1,1) PRIMARY KEY,
BilldID INT NOT NOT NULL REFERENCES dbo.Bill(BilldID),
ItemID INT NOT NULL REFERENCES dbo.Item(ItemID),
UNIQUE (BillID, ItemID) -- Unique constraint created in order to prevent duplicated rows
);
In this case, one bill with two items means I have to insert two rows into dbo.BillItem
table.
2) Back to original request: for one time task I would use XML and XQuery thus (this solution ends with a SELECT statement but it's trivial to convert into UPDATE):
DECLARE @iCountRef VARCHAR(100) = '1,2,3'
DECLARE @SourceTable TABLE (
BillId INT,
LineReference VARCHAR(8000)
)
INSERT @SourceTable (BillId, LineReference)
VALUES
(100, '1,2,'),
(100, '1,2,40,34'),
(100, '1'),
(100, '12')
DECLARE @iCountRefAsXML XML = CONVERT(XML, '' + REPLACE(@iCountRef, ',', '') + '')
SELECT *, STUFF(z.LineReferenceAsXML.query('
for $i in (x/y)
for $j in (a/b)
where data(($i/text())[1]) eq data(($j/text())[1])
return concat(",", ($i/text())[1])
').value('.', 'VARCHAR(8000)'), 1, 1, '') AS NewLineReference
FROM (
SELECT *, CONVERT(XML,
'' + REPLACE(LineReference, ',', ' ') + ' ' +
'' + REPLACE(@iCountRef, ',', '') + ''
) AS LineReferenceAsXML
FROM @SourceTable s
) z
Results:
BillId LineReference NewLineReference LineReferenceAsXML
----------- ------------- ---------------- ------------------------------------------------------------------------
100 1,2, 1 ,2 1 2 123
100 1,2,40,34 1 ,2 1 2 40 34 123
100 1 1 1 123
100 12 (null) 12 123