Wprowadzenie
Dzisiejszy artykuł pochodzi ze scenariusza, którego doświadczyliśmy w praktyce jakiś czas temu. Zarządzaliśmy kartowym systemem transakcyjnym o nazwie Postilion i musieliśmy zaktualizować dane w kolumnie zawierającej adresy IP jako część ciągu o nowy adres IP. Było to konieczne, ponieważ adres IP serwera, na którym znajduje się rozwiązanie, zwykle zmieniał się z powodu przełączenia lub przywrócenia danych do środowiska UAT.
Dane o serwerze były przechowywane w bazach danych i nie było możliwości ich aktualizacji z poziomu aplikacji bez przechodzenia wiersz po wierszu. W związku z tym musieliśmy wymyślić wydajne rozwiązanie wykorzystujące funkcje serwera SQL LEN i SUBSTRING (lub REPLACE).
Odtwarzanie środowiska
W tej demonstracji odtwarzamy tylko tabelę wymaganą do pokazania tego, co zrobiliśmy. Oczywiście dane nie są takie same jak w produkcji.
Listing 1 pokazuje, jak tworzymy i wypełniamy naszą przykładową tabelę:
-- 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');
Ta tabela zawiera kilka prostych kolumn. Interesującą kolumną jest tutaj adres kolumna. Naszym zadaniem jest zmiana adresu IP z 10.2.100.42 na 10.2.100.79.
Jak pokazano na rysunku 1, dane przechowywane w kolumnie adresu to nie sam adres IP. Jest to ciąg, a adres IP to tylko jego część. Dlatego nie możemy zrobić prostej aktualizacji. Każdy wiersz ma inną wartość i musimy wyizolować ostatni oktet adresu IP i tam dokonać zmiany.
Zamień część ciągu w SQL Server za pomocą funkcji SUBSTRING()
Aby spełnić wymagania zadania, używamy dwóch prostych funkcji:funkcji LEN() i funkcji SUBSTRING(). Podamy przykład SUBSTRING w SQL Server.
- SQL LEN() funkcja zwraca liczbę znaków w ciągu. Jest to ważne dla naszego rozwiązania, ponieważ oryginalne dane były nieco zabrudzone – nie wszystko w kolumnie adresu było adresem IP. Dlatego musimy zapewnić aktualizację tego, co zamierzaliśmy zaktualizować.
- Serwer SQL SUBSTRING() funkcja zwraca część wyrażenia znakowego, binarnego, tekstowego lub graficznego w SQL Server. Używamy go, aby upewnić się, że zmienimy tę część ciągu w kolumnie adresu, którą chcemy zmienić – rzeczywisty adres IP.
Listing 2 i rysunek 2 przedstawiają kod wizualizacji wyniku zamiany .42 na .79 w kolumnie adresu.
-- 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
Uwaga:wygenerowaliśmy kolumnę obliczeniową. W ten sposób możemy porównać oryginalne wartości ze zmianami, zanim zastosujemy te zmiany.
Aktualizuj część ciągu w SQL za pomocą funkcji REPLACE()
Moglibyśmy to zrobić prościej, używając funkcji REPLACE(). Zamienia wszystkie wystąpienia określonej wartości ciągu na inną wartość ciągu.
Funkcja REPLACE zwraca ciąg, w którym zastępuje podciąg innym podciągiem.
Spójrz na kod z Listingu 3. Otrzymujemy dokładnie taki sam wynik, jak pokazano na Rysunku 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
Składnia funkcji SUBSTRING w instrukcji UPDATE
Zwizualizujmy nasze rozwiązanie za pomocą instrukcji SELECT. Musimy zobaczyć, gdzie włączyliśmy funkcję LEN() wraz z funkcją SUBSTRING() lub łatwiejszą funkcją REPLACE().
Listing 4 pokazuje, jak wykonujemy instrukcję UPDATE. Dla bezpieczeństwa dołączamy go do transakcji. Jeśli coś jest nie tak, będziemy mogli to cofnąć.
-- 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
Jeśli jesteśmy zadowoleni z wyników, po prostu zobowiązujemy się.
Używanie funkcji SQL REPLACE w instrukcji UPDATE
Te same wyniki możemy osiągnąć za pomocą funkcji REPLACE() w SQL (patrz Listing 5). Działa to ze względu na nasze specyficzne dane, „.42” występuje TYLKO RAZ w każdym wierszu.
-- 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
Wniosek
W ten sposób pokazaliśmy, jak zamienić część niektórych ciągów w kolumnie za pomocą funkcji SUBSTRING i REPLACE. Powodzenie zadania zależy od właściwego zrozumienia danych. Oczywiście musimy współpracować z programistami i specjalistami posiadającymi niezbędne doświadczenie, aby przewidzieć konsekwencje wszelkich błędów w aplikacji.
Ponadto podjęliśmy środki ostrożności:
- Użyliśmy instrukcji SELECT i kolumny obliczeniowej, aby określić, jak będą wyglądać ostateczne wyniki.
- Załączyliśmy nasze oświadczenie UPDATE w transakcji, aby zapewnić cofnięcie opcja.
Możesz pójść dalej w podejmowaniu środków ostrożności i wykonać kopię zapasową bazy danych:
Referencje
- Funkcja LEN()
- Funkcja SUBSTRING()
- Funkcja ZAMIEŃ