Въведение
Днешната статия идва от сценарий, който преживяхме на практика преди време. Управлявахме система за транзакции с карти, наречена Postilion, и трябваше да актуализираме данните в колона, съдържаща IP адреси като част от низа с нов IP адрес. Това беше необходимо, тъй като IP адресът на сървъра, хостващ решението, обикновено се променя поради превключване или възстановяване на данни към UAT среда.
Данните за сървъра се съхраняваха в базите данни и нямаше начин да се актуализират същите от приложението, без да се преминава ред по ред. По този начин трябваше да измислим ефективно решение, използвайки функциите LEN и SUBSTRING (или REPLACE) на SQL Server.
Възпроизвеждане на околната среда
За тази демонстрация ние възпроизвеждаме само таблицата, необходима, за да покажем какво сме направили. Разбира се, данните не са същите като в производството.
Списък 1 показва как създаваме и попълваме нашата примерна таблица:
-- Listing 1: Create and Populate Node_Saps Table
create database postilion;
use postilion
go
-- drop table node_saps
create table node_saps (
[node] varchar(50)
,[sap] varchar(50)
,[type] varchar(50)
,[protocol] varchar(50)
,[address] varchar(50)
,[setup_data] varchar(50)
,[secure] varchar(50)
,[max_nr_conn] varchar(50)
,[msg_mode] varchar(50)
,[nr_active_conns] varchar(50)
,[filter_properties] varchar(50)
)
use postilion
go
insert into node_saps values ('EGH01',2,'sink','TCP','10.2.100.42_atm_ghana', 100,'YES',10,'open',5,'intense');
insert into node_saps values ('EGH02',3,'sink','TCP','10.2.100.42_atm_ghana', 120,'YES',10,'open',5,'moderate');
insert into node_saps values ('ENG01',4,'source','TCP','10.2.100.42_atm_nigeria', 175,'YES',40,'open',19,'premium');
insert into node_saps values ('EBF01',6,'sink','TCP','10.2.100.42_atm_burkina', 122,'YES',20,'open',4,'intense');
insert into node_saps values ('EGQ01',7,'sink','TCP','10.2.100.42_atm_equatorial', 200,'YES',10,'open',2,'moderate');
Тази таблица съдържа няколко прости колони. Колоната на интерес тук е адрес колона. Нашата задача е да променим IP адреса от 10.2.100.42 на 10.2.100.79.
Както е показано на фигура 1, данните, съхранявани в адресната колона, не са само IP адресът. Това е низ, а IP адресът е само част от него. Следователно не можем да направим проста актуализация. Всеки ред има различна стойност и трябва да изолираме последния октет от IP адреса и да направим промяната там.
Заменете част от низ в SQL Server с помощта на функция SUBSTRING()
За да постигнем изискванията на задачата, използваме две прости функции:функцията LEN() и функцията SUBSTRING(). Ще предоставим SUBSTRING в SQL Server с пример.
- SQL LEN() функцията връща броя на знаците в низ. Това е важно за нашето решение, защото първоначалните данни бяха малко мръсни – не всичко в колоната за адрес е IP адрес. По този начин трябва да гарантираме, че актуализираме това, което възнамеряваме да актуализираме.
- SQL Server SUBSTRING() функцията връща част от символен, двоичен, текстов или графичен израз в SQL Server. Използваме го, за да гарантираме, че ще променим тази част от низа в адресната колона, която искаме да променим – действителния IP адрес.
Списък 2 и Фигура 2 показват кода за визуализиране на резултата от замяната на .42 с .79 в адресната колона.
-- Listing 2: Select Statement to Verify Solution
USE postilion
GO
SELECT [node]
,[sap]
,[type]
,[protocol]
,[address]
,substring (address,1,9) + '79' + substring (address,12,20) manrep
,[setup_data]
,[secure]
,[max_nr_conn]
,[msg_mode]
,[nr_active_conns]
,[filter_properties]
FROM [postilion].[dbo].[node_saps]
WHERE len(address) > 10
Забележка:Генерирахме изчислена колона. По този начин можем да сравним първоначалните стойности с промените, преди да приложим тези промени.
Актуализиране на част от низ в SQL с помощта на функцията REPLACE()
Можехме да направим това по-просто, като използваме функцията REPLACE(). Той заменя всички поява на определена низова стойност с друга низова стойност.
Функцията REPLACE връща низ, където замества подниз с друг подниз.
Разгледайте кода в листинг 3. Получаваме точно същия резултат, както е показано на фигура 2.
-- Listing 3: Select Statement to Verify Solution Using REPLACE()
USE postilion
GO
SELECT [node]
,[sap]
,[type]
,[protocol]
,[address]
,replace(address,'.42','.79') rep
,[setup_data]
,[secure]
,[max_nr_conn]
,[msg_mode]
,[nr_active_conns]
,[filter_properties]
FROM [postilion].[dbo].[node_saps]
WHERE len(address) > 10
Синтаксис за функция SUBSTRING в изявление UPDATE
Нека визуализираме нашето решение с помощта на оператора SELECT. Трябва да видим къде сме включили функцията LEN() заедно с функцията SUBSTRING() или по-лесната функция REPLACE().
Списък 4 показва как изпълняваме оператора UPDATE. За безопасност ние го включваме в транзакция. Ако нещо не е наред, ще можем да го върнем обратно.
-- Listing 4: UPDATE Statement Using SUBSTRING()
BEGIN TRAN
update [postilion].[dbo].[node_saps]
set address=substring (address,1,9) + '79' + substring (address,12,20)
where substring (address,10,2)= '42' and
len(address) > 10
SELECT * FROM [postilion].[dbo].[node_saps]
--ROLLBACK
--COMMIT
Ако сме доволни от резултатите, просто се ангажираме.
Използване на функцията SQL REPLACE в израз UPDATE
Можем да постигнем същите резултати с помощта на функцията REPLACE() в SQL (вижте листинг 5). Това работи поради нашите специфични данни, „.42“ се среща САМО ВЕДНЪЖ на всеки ред.
-- Listing 5: UPDATE Statement Using REPLACE()
BEGIN TRAN
update [postilion].[dbo].[node_saps]
set address=replace(address,'.42','.79')
where substring (address,10,2)= '42' and
len(address) > 10
SELECT * FROM [postilion].[dbo].[node_saps]
--ROLLBACK
--COMMIT
Заключение
По този начин ние демонстрирахме как да заменим част от някои низове в колоната с помощта на функции SUBSTRING и REPLACE. Успехът на задачата зависи от правилното разбиране на включените данни. Разбира се, трябва да си сътрудничим с разработчиците и специалистите, които имат необходимия опит, за да предвидят последиците от всякакви грешки в дадено приложение.
Освен това взехме предпазни мерки:
- Използвахме израза SELECT и изчислена колона, за да определим как ще изглеждат евентуалните резултати.
- Приложихме нашия оператор UPDATE в транзакция, за да гарантираме връщане назад опция.
Може да отидете по-далеч в вземането на предпазни мерки и да направите резервно копие на базата данни:
Препратки
- Функцията LEN()
- Функцията SUBSTRING()
- Функция REPLACE