可変アルファ長の列にダーティデータがあります。 0〜9以外のものはすべて取り除きたいだけです。
関数またはprocを実行したくありません。私はテキストの後に数値を取得するだけのようなスクリプトを持っています、それは次のように見えます:
Update TableName
set ColumntoUpdate=cast(replace(Columnofdirtydata,'Alpha #','') as int)
where Columnofdirtydata like 'Alpha #%'
And ColumntoUpdate is Null
私は、Alpha#12345789の形式ではないだろうと思ったデータフィールドの一部が、.
除去する必要があるデータの例
AB ABCDE # 123
ABCDE# 123
AB: ABC# 123
123のみが必要です。すべてのデータフィールドに番号の前に#が付いているのは事実です。
部分文字列とPatIndexを試しましたが、構文が正しくなっていません。誰もこれに対処するための最良の方法に関するアドバイスがありますか?
ありがとうございました!
SQL Serverの文字列から数値を抽出する方法については、こちらをご覧ください ブログ投稿 以下は、例で文字列を使用したサンプルです。
DECLARE @textval NVARCHAR(30)
SET @textval = 'AB ABCDE # 123'
SELECT LEFT(SUBSTRING(@textval, PATINDEX('%[0-9.-]%', @textval), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(@textval, PATINDEX('%[0-9.-]%', @textval), 8000) + 'X') -1)
数字の間にいくつかの文字(例:桁区切り記号)がある場合は、次のことを試してください:
declare @table table (DirtyCol varchar(100))
insert into @table values
('AB ABCDE # 123')
,('ABCDE# 123')
,('AB: ABC# 123')
,('AB#')
,('AB # 1 000 000')
,('AB # 1`234`567')
,('AB # (9)(876)(543)')
;with tally as (select top (100) N=row_number() over (order by @@spid) from sys.all_columns),
data as (
select DirtyCol, Col
from @table
cross apply (
select (select C + ''
from (select N, substring(DirtyCol, N, 1) C from tally where N<=datalength(DirtyCol)) [1]
where C between '0' and '9'
order by N
for xml path(''))
) p (Col)
where p.Col is not NULL
)
select DirtyCol, cast(Col as int) IntCol
from data
出力は次のとおりです。
DirtyCol IntCol
--------------------- -------
AB ABCDE # 123 123
ABCDE# 123 123
AB: ABC# 123 123
AB # 1 000 000 1000000
AB # 1`234`567 1234567
AB # (9)(876)(543) 9876543
更新するには、ColToUpdate
を追加して、data
cteのリストを選択します。
;with num as (...),
data as (
select ColToUpdate, /*DirtyCol, */Col
from ...
)
update data
set ColToUpdate = cast(Col as int)
これは私にとってうまくいきます:
CREATE FUNCTION [dbo].[StripNonNumerics]
(
@Temp varchar(255)
)
RETURNS varchar(255)
AS
Begin
Declare @KeepValues as varchar(50)
Set @KeepValues = '%[^0-9]%'
While PatIndex(@KeepValues, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
Return @Temp
End
次に、そのように関数を呼び出して、サニタイズされたものの隣にある元の何かを確認します。
SELECT Something, dbo.StripNonNumerics(Something) FROM TableA
サーバーがTRANSLATE機能をサポートしている場合のエレガントなソリューションを次に示します(SQLサーバーでは、SQLサーバー2017+およびSQL Azureでも利用可能です)。
まず、数字以外の文字を@文字に置き換えます。次に、すべての@文字を削除します。 TRANSLATE呼び出しの2番目のパラメーターに存在することがわかっている文字を追加する必要がある場合があります。
select REPLACE(TRANSLATE([Col], 'abcdefghijklmnopqrstuvwxyz+()- ,#+', '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'), '@', '')
Ken's answerに追加するために、これはコンマとスペースと括弧を処理します
--Handles parentheses, commas, spaces, hyphens..
declare @table table (c varchar(256))
insert into @table
values
('This is a test 111-222-3344'),
('Some Sample Text (111)-222-3344'),
('Hello there 111222 3344 / How are you?'),
('Hello there 111 222 3344 ? How are you?'),
('Hello there 111 222 3344. How are you?')
select
replace(LEFT(SUBSTRING(replace(replace(replace(replace(replace(c,'(',''),')',''),'-',''),' ',''),',',''), PATINDEX('%[0-9.-]%', replace(replace(replace(replace(replace(c,'(',''),')',''),'-',''),' ',''),',','')), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(replace(replace(replace(replace(replace(c,'(',''),')',''),'-',''),' ',''),',',''), PATINDEX('%[0-9.-]%', replace(replace(replace(replace(replace(c,'(',''),')',''),'-',''),' ',''),',','')), 8000) + 'X') -1),'.','')
from @table
CREATE FUNCTION FN_RemoveNonNumeric (@Input NVARCHAR(512))
RETURNS NVARCHAR(512)
AS
BEGIN
DECLARE @Trimmed NVARCHAR(512)
SELECT @Trimmed = @Input
WHILE PATINDEX('%[^0-9]%', @Trimmed) > 0
SELECT @Trimmed = REPLACE(@Trimmed, SUBSTRING(@Trimmed, PATINDEX('%[^0-9]%', @Trimmed), 1), '')
RETURN @Trimmed
END
GO
SELECT dbo.FN_RemoveNonNumeric('ABCDE# 123')
Declare @MainTable table(id int identity(1,1),TextField varchar(100))
INSERT INTO @MainTable (TextField)
VALUES
('6B32E')
declare @i int=1
Declare @originalWord varchar(100)=''
WHile @i<=(Select count(*) from @MainTable)
BEGIN
Select @originalWord=TextField from @MainTable where id=@i
Declare @r varchar(max) ='', @len int ,@c char(1), @x int = 0
Select @len = len(@originalWord)
declare @pn varchar(100)=@originalWord
while @x <= @len
begin
Select @c = SUBSTRING(@pn,@x,1)
if(@c!='')
BEGIN
if ISNUMERIC(@c) = 0 and @c <> '-'
BEGIN
Select @r = cast(@r as varchar) + cast(replace((SELECT ASCII(@c)-64),'-','') as varchar)
end
ELSE
BEGIN
Select @r = @r + @c
END
END
Select @x = @x +1
END
Select @r
Set @i=@i+1
END
答えは次のとおりです。
DECLARE @t TABLE (tVal VARCHAR(100))
INSERT INTO @t VALUES('123')
INSERT INTO @t VALUES('123S')
INSERT INTO @t VALUES('A123,123')
INSERT INTO @t VALUES('a123..A123')
;WITH cte (original, tVal, n)
AS
(
SELECT t.tVal AS original,
LOWER(t.tVal) AS tVal,
65 AS n
FROM @t AS t
UNION ALL
SELECT tVal AS original,
CAST(REPLACE(LOWER(tVal), LOWER(CHAR(n)), '') AS VARCHAR(100)),
n + 1
FROM cte
WHERE n <= 90
)
SELECT t1.tVal AS OldVal,
t.tval AS NewVal
FROM (
SELECT original,
tVal,
ROW_NUMBER() OVER(PARTITION BY tVal + original ORDER BY original) AS Sl
FROM cte
WHERE PATINDEX('%[a-z]%', tVal) = 0
) t
INNER JOIN @t t1
ON t.original = t1.tVal
WHERE t.sl = 1
Create function fn_GetNumbersOnly(@pn varchar(100))
Returns varchar(max)
AS
BEGIN
Declare @r varchar(max) ='', @len int ,@c char(1), @x int = 0
Select @len = len(@pn)
while @x <= @len
begin
Select @c = SUBSTRING(@pn,@x,1)
if ISNUMERIC(@c) = 1 and @c <> '-'
Select @r = @r + @c
Select @x = @x +1
end
return @r
End
これは、文字列からすべての数字を取得するバージョンです。つまり、I'm 35 years old; I was born in 1982. The average family has 2.4 children.
を指定すると、35198224
が返されます。つまり、コードとしてフォーマットされている可能性のある数値データ(例:#123,456,789
/123-00005
)があるのは良いことですが、特定の数値を引き出す場合は適切ではありません(つまり、テキストの数字/数字だけではなく)。また、数字のみを処理します。そのため、負の符号(-
)またはピリオド.
)は返されません。
declare @table table (id bigint not null identity (1,1), data nvarchar(max))
insert @table (data)
values ('hello 123 its 45613 then') --outputs: 12345613
,('1 some other string 98 example 4') --outputs: 1984
,('AB ABCDE # 123') --outputs: 123
,('ABCDE# 123') --outputs: 123
,('AB: ABC# 123') --outputs: 123
; with NonNumerics as (
select id
, data original
--the below line replaces all digits with blanks
, replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(data,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''),'8',''),'9','') nonNumeric
from @table
)
--each iteration of the below CTE removes another non-numeric character from the original string, putting the result into the numerics column
, Numerics as (
select id
, replace(original, substring(nonNumeric,1,1), '') numerics
, replace(nonNumeric, substring(nonNumeric,1,1), '') charsToreplace
, len(replace(nonNumeric, substring(nonNumeric,1,1), '')) charsRemaining
from NonNumerics
union all
select id
, replace(numerics, substring(charsToreplace,1,1), '') numerics
, replace(charsToreplace, substring(charsToreplace,1,1), '') charsToreplace
, len(replace(charsToreplace, substring(charsToreplace,1,1), '')) charsRemaining
from Numerics
where charsRemaining > 0
)
--we select only those strings with `charsRemaining=0`; i.e. the rows for which all non-numeric characters have been removed; there should be 1 row returned for every 1 row in the original data set.
select * from Numerics where charsRemaining = 0
このコードは、指定された文字列からすべての数字(つまり、必要な文字)を空白で置き換えることによって削除することで機能します。次に、元の文字列(数字を含む)を調べて、残っていたすべての文字(数字以外の文字)を削除し、数字のみを残します。
最初に数字以外の文字をすべて削除するのではなく、2つのステップでこれを行う理由は、可能な文字が非常に多いのに10桁しかないためです。そのため、その小さなリストの置き換えは比較的高速です。次に、実際に文字列に存在する非数値文字のリストを提供するため、その小さなセットを置き換えることができます。
このメソッドは、共通テーブル式(CTE)を使用して、再帰SQLを利用します。
あなたの場合、#は常に#記号の後にあるように思われるので、LTRIM()とRTRIM()でCHARINDEX()を使用するとおそらく最高のパフォーマンスを発揮します。しかし、ここには、数字以外を削除する興味深い方法があります。集計表と数字の表を使用して、受け入れられる文字を制限し、XML技術を使用して、数字以外の文字を含まない単一の文字列に連結します。このテクニックのすばらしい点は、許可されている任意の文字を含めるように拡張し、許可されていないものをすべて削除できることです。
DECLARE @ExampleData AS TABLE (Col VARCHAR(100))
INSERT INTO @ExampleData (Col) VALUES ('AB ABCDE # 123'),('ABCDE# 123'),('AB: ABC# 123')
DECLARE @Digits AS TABLE (D CHAR(1))
INSERT INTO @Digits (D) VALUES ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9')
;WITH cteTally AS (
SELECT
I = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
@Digits d10
CROSS APPLY @Digits d100
--add more cross applies to cover longer fields this handles 100
)
SELECT *
FROM
@ExampleData e
OUTER APPLY (
SELECT CleansedPhone = CAST((
SELECT TOP 100
SUBSTRING(e.Col,t.I,1)
FROM
cteTally t
INNER JOIN @Digits d
ON SUBSTRING(e.Col,t.I,1) = d.D
WHERE
I <= LEN(e.Col)
ORDER BY
t.I
FOR XML PATH('')) AS VARCHAR(100))) o
これは私のために働いた:
一重引用符を削除しました。
次に、","
を"."
に置き換えます。
きっとこれは誰かを助けるでしょう:
" & txtFinalscore.Text.Replace(",", ".") & "
置換パターンなどの正規表現を使用できるようにするために、SQL CLRスカラー関数を作成できます。
ここ このような関数を作成する方法の例を見つけることができます。
このような機能を使用すると、次の行だけで問題を解決できます。
SELECT [dbo].[fn_Utils_RegexReplace] ('AB ABCDE # 123', '[^0-9]', '');
SELECT [dbo].[fn_Utils_RegexReplace] ('ABCDE# 123', '[^0-9]', '');
SELECT [dbo].[fn_Utils_RegexReplace] ('AB: ABC# 123', '[^0-9]', '');
さらに重要なことは、正規表現がT-SQLステートメントにまったく新しい世界のオプションを直接もたらすため、より複雑な問題を解決できることです。
私はこのための関数を作成しました
Create FUNCTION RemoveCharacters (@text varchar(30))
RETURNS VARCHAR(30)
AS
BEGIN
declare @index as int
declare @newtexval as varchar(30)
set @index = (select PATINDEX('%[A-Z.-/?]%', @text))
if (@index =0)
begin
return @text
end
else
begin
set @newtexval = (select STUFF ( @text , @index , 1 , '' ))
return dbo.RemoveCharacters(@newtexval)
end
return 0
END
GO