2012-12-12 12 views
7

Ich benutze SQL Server 2008.Character Maske Ausgabedaten auf wählen

Ich möchte die Ausgangsdaten einer Abfrage Zeichenmaske.

Dies ist meine Daten aus einer Spalte in einer Tabelle, wenn ein Auswahl tun:

column1 

384844033434 

743423547878 

111224678885 

Ich würde eine Ausgabe wie folgt erhalten:

column1 

384xxxxxx434 

743xxxxxx878 

111xxxxxx885 

Wie kann ich das tun?

+2

Sieht aus wie du über [Maskierung von Zeichen] (http://www.simple-talk.org) sprichst.com/sql/database-administration/obfuscating-your-sql-server-data /) anstelle der verschlüsselung –

+0

yea ist zeichen maskierung – pyram

Antwort

7

Sie müssten eine Ansicht verwenden und allen Benutzern den SELECT-Zugriff auf die zugrunde liegende Tabelle verweigern.

Ihre Ansicht würde in etwa so aussehen

SELECT 
    SUBSTRING(x.SecurityNumber,1,3) + 
    'xxxxx' + 
    SUBSTRING(x.SecurityNumber,LEN(x.SecurityNumber) - 2, LEN(x.SecurityNumber)) 
    AS column1 
FROM underlyingTable x 

Sie könnten dann an die Benutzer SELECT-Zugriff gewähren nur diese Ansicht und haben die in der Art und Weise maskiert Sie beschrieben.

Wenn Sie möchten, dass Ihre Client-Software Daten in diese Tabelle einfügen oder aktualisieren kann, verwenden Sie einen INSTEAD OF INSERT- oder INSTEAD OF UPDATE-Trigger, um die Basistabelle zu aktualisieren.

+0

Danke und vielen dank für die antworten! – pyram

+0

Ich verwende sqlcmd für SQL Server 2008 und festgestellt, dass die Offsets unterschiedlich sind. Für die korrekte Ausgabe habe ich 'SUBSTRING (x.SecurityNumber, 1,3) + 'xxxxx' + SUBSTRING (x.SecurityNumber, LEN (x.SecurityNumber) - 2, LEN (x.SecurityNumber))' – David

+0

Dank @David verwendet. Entsprechend bearbeitet. –

1

Eine einfache Auswahlabfrage würde genau das zurückbringen, was sie auf dem Tisch hat, egal ob sie verschlüsselt ist oder nicht.

Also, ich denke, Sie können dies nicht auf der Datenbankebene tun.

Für Ihre Anforderung benötigen Sie einen bidirektionalen Verschlüsselungsalgorithmus zur Verwendung in Ihrer Anwendung. Sie können also Daten verschlüsseln, bevor sie verschlüsselt in der Datenbank gespeichert werden, und die verschlüsselten Informationen aus der Datenbank abrufen und auf Ihrer Anwendung entschlüsseln.

2

Wenn Sie wissen, wie lange Ihr Datenfeld sein wird, dann können Sie die statische Version verwenden, die andere Antwort produzieren, aber man kann immer eine Funktion erstellen, um diese zu generieren:

CREATE FUNCTION MixUpCharacters 
(
    @OrigVal varchar(max) 
) 
RETURNS varchar(max) 
AS 
BEGIN 

DECLARE @NewVal varchar(max) 
DECLARE @OrigLen int 
DECLARE @LoopCt int 
DECLARE @Part varchar(max) = '' 
Declare @PartLength int 

SET @NewVal = '' 
SET @OrigLen = DATALENGTH(@OrigVal) 
SET @LoopCt = 1 

SET @Part = SUBSTRING(@OrigVal, 4, len(@OrigVal)-6) 
set @PartLength = LEN(@Part) 

WHILE @LoopCt <= @PartLength 
    BEGIN 
     -- Current length of possible characters 
     SET @NewVal = @NewVal + 'X' 

     -- Advance the loop 
     SET @LoopCt = @LoopCt + 1 
    END 

    Return REPLACE(@OrigVal, @Part, @NewVal) 
END 

Hierzu Funktion übergeben Sie die Werte, die Sie maskieren möchten.So Ihre Frage wäre:

declare @temp table 
(
    col1 varchar(50) 
) 

insert into @temp 
values ('384844033434'), ('743423547878'), ('111224678885') 

select dbo.MixUpCharacters(col1) col1 
from @temp 

Siehe SQL Fiddle with Demo

Das Ergebnis wäre:

|   COL1 | 
---------------- 
| 384XXXXXX434 | 
| 743XXXXXX878 | 
| 111XXXXXX885 | 

Oder hier ist ein Weg, um es mit rekursiven CTE zu tun:

;with data(col1) as 
(
    select '384844033434' 
    union all 
    select '7434235878' 
    union all 
    select '111224678885' 
), 
s1 (col1, repfull) as 
(
    select col1, 
     SUBSTRING(col1, 4, len(col1)-6) repfull 
    from data 
), 
s2 (col1, item, repfull, r) as 
(
    select col1, 
     cast('x' as varchar(max)), 
     right(repfull, LEN(repfull)-1), 
     repfull 
    from s1 
    union all 
    select col1, 
     'x'+ cast(item as varchar(max)), 
     right(repfull, LEN(repfull)-1), 
     r 
    from s2 
    where len(repfull) >0 
) 
select REPLACE(col1, r, item) newValue 
from 
(
    select col1, item, R, 
     ROW_NUMBER() over(partition by col1 order by len(item) desc) rn 
    from s2 
) src 
where rn = 1 

Siehe SQL Fiddle with Demo

1

sehr einfach bro

SELECT CONCAT (SUBSTR('Your string',1,3),LPAD(SUBSTR('Your string',-3),LENGTH('Your string')-1,'*')) RESULT FROM dual 

Ausgang:

Sie ******* ing

wenn es num Typ char

1

konvertieren Wenn Sie möchten, Feld zu maskieren, das Sie nicht über Feldlänge wissen. Sie können bluefeet den Code wie folgt aktualisieren:

ALTER FUNCTION MixUpCharacters 
(
    @OrigVal varchar(MAX) 
) 
RETURNS varchar(MAX) 
AS 
BEGIN 

DECLARE @NewVal NVARCHAR(MAX) 
DECLARE @OrigLen INT 
DECLARE @LoopCt INT 
DECLARE @Part NVARCHAR(MAX) = '' 
DECLARE @PartLength INT  -- MastLength 
DECLARE @PartStartIndex INT -- MaskStartIndex 

SET @NewVal = '' 
SET @LoopCt = 1 
SET @OrigLen = LEN(@OrigVal) 

IF(@OrigLen = 1) 
    BEGIN 
     RETURN 'X' 
    END 
IF(@OrigLen < 6) 
    BEGIN 
     SET @PartStartIndex = @OrigLen/2 
     SET @PartLength = @OrigLen - @PartStartIndex 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 
ELSE IF(@OrigLen < 8) 
    BEGIN 
     SET @PartStartIndex = 3 
     SET @PartLength = @OrigLen - @PartStartIndex - 1 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 
ELSE 
    BEGIN 
     SET @PartStartIndex = 4 
     SET @PartLength = @OrigLen - @PartStartIndex - 2 
     SET @Part = SUBSTRING(@OrigVal, @PartStartIndex, @PartLength) 
    END 

WHILE @LoopCt <= @PartLength 
    BEGIN 
     -- Current length of possible characters 
     SET @NewVal = @NewVal + 'X' 

     -- Advance the loop 
     SET @LoopCt = @LoopCt + 1 
    END 

    RETURN REPLACE(@OrigVal, @Part, @NewVal) 
END 

Sie mögen diese testen können:

SELECT dbo.MixUpCharacters('1') 
UNION ALL 
SELECT dbo.MixUpCharacters('12') 
UNION ALL 
SELECT dbo.MixUpCharacters('123') 
UNION ALL 
SELECT dbo.MixUpCharacters('1234') 
UNION ALL 
SELECT dbo.MixUpCharacters('12345') 
UNION ALL 
SELECT dbo.MixUpCharacters('123456') 
UNION ALL 
SELECT dbo.MixUpCharacters('1234567') 
UNION ALL 
SELECT dbo.MixUpCharacters('12345678') 
UNION ALL 
SELECT dbo.MixUpCharacters('123456789') 
UNION ALL 
select dbo.MixUpCharacters('1234567890') 
UNION ALL 
select dbo.MixUpCharacters('12345678910') 

ERGEBNISSE:

X 
X2 
XX3 
1XX4 
1XXX5 
12XX56 
12XXX67 
123XX678 
123XXX789 
123XXXX890 
123XXXXX910 
0

Von SQL Server 2016+ Sie Dynamic Data Masking Funktion nutzen könnten.

Die dynamische Datenmaskierung begrenzt die sensible Datenexponierung, indem sie für nicht berechtigte Benutzer maskiert wird. Die dynamische Datenmaskierung verhindert den unbefugten Zugriff auf vertrauliche Daten, da Kunden festlegen können, wie viele sensible Daten mit minimaler Auswirkung auf die Anwendungsschicht offengelegt werden sollen. Es ist eine Datenschutzfunktion, die die sensiblen Daten in der Ergebnismenge einer Abfrage über ausgewiesene Datenbankfelder ausblendet, während die Daten in der Datenbank nicht geändert werden. Die dynamische Datenmaskierung ist mit vorhandenen Anwendungen einfach zu handhaben, da Maskierungsregeln in den Abfrageergebnissen angewendet werden. Viele Anwendungen können vertrauliche Daten maskieren, ohne vorhandene Abfragen zu ändern.

CREATE TABLE #tab(ID INT IDENTITY(1,1), column1 VARCHAR(12)); 

INSERT INTO #tab(column1) 
VALUES('384844033434'),('743423547878'),('111224678885'); 

SELECT * FROM #tab; 

Ausgang:

╔════╦══════════════╗ 
║ ID ║ column1 ║ 
╠════╬══════════════╣ 
║ 1 ║ 384844033434 ║ 
║ 2 ║ 743423547878 ║ 
║ 3 ║ 111224678885 ║ 
╚════╩══════════════╝ 

ALTER TABLE #tab 
ALTER COLUMN column1 VARCHAR(12) MASKED WITH (FUNCTION = 'partial(3,"xxxxxx",3)'); 

SELECT * FROM #tab; 

Ausgang:

╔════╦══════════════╗ 
║ ID ║ column1 ║ 
╠════╬══════════════╣ 
║ 1 ║ 384xxxxxx434 ║ 
║ 2 ║ 743xxxxxx878 ║ 
║ 3 ║ 111xxxxxx885 ║ 
╚════╩══════════════╝ 

LiveDemo