Remove characters from text using TRANSLATE function (replace them with empty strings) - sql-server

Let's say I have a string:
DECLARE #text VARCHAR(20) = 'abr_akad-ab#ra';
and I want to remove all _-# characters from the text.
Normally I would user REPLACE function to that, something like:
SELECT REPLACE(REPLACE(REPLACE(#text, '-', ''), '_', ''),'#','')
Can I do that with single TRANSLATE statement somehow?

You can try the following query:
DECLARE #text AS VARCHAR(20) = 'abr_akad-ab#ra';
SELECT REPLACE(TRANSLATE(#text, '_-#', '###'), '#', '')
it will return the output as abrakadabra
Working demo on db<>fiddle

You'll still need use REPLACE at some point, as SQL Server requires that the length of parameters 2 and 3 for TRANSLATE are the same length. As such an expression like the below will error:
TRANSLATE(YourColumn, '-_#','')
Therefore what you could do it replace them all with a different character using TRANSLATE, and then replace that one character:
REPLACE(TRANSLATE(YourColumn, '-_#','|||'),'|','')

Related

changing type of column to array Postgresql

I am trying to convert text column to array[text] column in table i have column entry like
['Nikolai Rimsky-Korsakov', 'Jascha Heifetz', 'Arpárd Sándor']
but this is one string or text format I want to convert it into a real array of a string so that I can access a particular name in the above column.
I tried converting the type from this link by setting it to type to text[] but the column is just becoming one element of an array like this.
[ "['Nikolai Rimsky-Korsakov', 'Jascha Heifetz', 'Arpárd Sándor']" ]
But what I wanted is to type Array[text] for tat column to able to access particular names.
Use the function translate() to replace square brackets with curly ones and remove single-quotes:
translate(str, '[]''', '{}')::text[]
See the full example in Db<>fiddle.
Section 8.15.2. Array Value Input of PostgreSQL documentation describes the general look of array to be
'{ val1 delim val2 delim ... }'
So you need to trim your '[' and ']' characters and replace them with '{' and '}'.
Then you can cast to text array (text[]) and enjoy the results.
SELECT
replace(
replace(
'{'||trim(BOTH '[]' FROM test.sample)||'}',
'\',
'\\'
),
'"',
'\"'
)::text[] AS names
FROM
(
SELECT '[''Nikolai Rimsky-Korsakov'', ''Jascha Heifetz'', ''Arpárd Sándor'', ''Joe "Wingy" Manone'']'::text AS sample
) test
EDIT 2
To handle cases when there " and '' characters in your input we must escape it with \.
SELECT
replace(
replace(
'{'||trim(BOTH '[]' FROM test.sample)||'}',
'\',
'\\'
),
'"',
'\"'
)::text[] AS names
FROM
(
SELECT '[''Nikolai Rimsky-Korsakov'', ''Jascha Heifetz'', ''Arpárd Sándor'', ''Joe "Wingy" Manone'']'::text AS sample
) test
EDIT 3
To remove quotes from names:
SELECT
replace(
replace(
replace(
'{'||trim(BOTH '[]''' FROM test.sample)||'}',
'\', '\\' ),
'"', '\"'),
''', ''', ',')::text[] AS names
FROM
(
SELECT '[''Nikolai Rimsky-Korsakov'', ''Jascha Heifetz'', ''Arpárd Sándor'', ''Joe "Wingy" Manone'']'::text AS sample
) test
The problem solved by removing nested square bracket from my CSV file before populating table and that using translate function with little bit of change thank
alter artist type text[] using translate(artist, '[]"', '{}')::text[] ; ```

SQL Server UDF Function to replace characters in column

I am trying to create a function in SQL server that takes a column name as a parameter this column contains first names of people, I manually inserted these names. Any name that contains a special character such as ' as in O'Brian I inserted the value as O$6Brian the $6 representing ' . The same for Jack & Jill the & I inserted as $7 so in the database this looks like Jack $7 Jill.
so when someone passes the name of the Names column which in my case is called fname into the function I would like the function to replace the $6 and $7 with the appropriate character.
I know this can be done using in the front end app but I just want to learn some more SQL hence why I am asking I have the following so far which does not work.
create function fn_convertDBChars(#stringtoconvert nvarchar)
returns nvarchar(20)
as
begin
declare #Return nvarchar(20)
select
#Return = case #stringtoconvert
when '$6' then REPLACE(#stringtoconvert, '$7', '&')
end
return #Return
end;
I would be grateful for any advice.
You were correct with most part of your function, except you should be using LIKE operator to match the patterns. You can replace $6 with single-quotes and $7 with & symbol in a user-defined function like this. Of course, you would be using the REPLACE function internally. Here is what your function would look like.
create function fn_convertDBChars(#stringtoconvert NVARCHAR(20))
returns nvarchar(20)
as
begin
declare #Return nvarchar(20)
select #Return = CASE WHEN #stringtoconvert LIKE '%$6%' then REPLACE(#stringtoconvert, '$6', '''')
WHEN #stringtoconvert LIKE '%$7%' THEN REPLACE(#stringtoconvert,'$7','&')
ELSE #stringtoconvert END
return #Return
end;
SELECT dbo.fn_convertDBChars('Jack $7 Jill') -- Returns Jack & Jill
SELECT dbo.fn_convertDBChars('O''Brian') -- Returns O'Brian
SELECT dbo.fn_convertDBChars(fname) from dbo.table_name -- This is how you would call your function on the column.
Notice the escape character used here to escape single-quotes. You can escape that by using two occurrences of single-quotes.
Just use the built-in function REPLACE like below:
set #Return = REPLACE(#stringtoconvert, '$7', '&')
where #stringtoconvert like '%$7%'

Sql Server wildcard Like Statement : How to use for data having undefined Length

I have URL data in a table like this(Showing only one row i have many more in table)
abc/portfolio/12/strategy
abc/portfolio/15/strategy
abc/portfolio/1/strategy
The data is in four part separated with '/'.
i got a string to match with this data, either i got a same string to match or if i can get "*" at any part of data if i don't need to match the particular part Like
abc/portfolio/*/strategy
if i get this string to match i don't have to match the '*' part,rest i need to match with the data. i need to match abc/portfolio/% with i need to Match %/strategy in a single column data.
i don't know how to do it with wildcards also as in data its not define that what is the length of a particular part.
As well as if i got two '**' then i need to match only intial Part of Data
Like if i get data to match abc/**/12/strategythen i only need to match abc\% in data.
Example:
Select Url_data from schema1.table1
where
url_data Like 'abc/portfolio/*/strategy'
here i need the "*" to work like, ignore the data in that particular Part.
outcome expected is :
abc/portfolio/12/strategy
abc/portfolio/15/strategy
abc/portfolio/1/strategy
Instead of "*" you can use '%' as follows
Select Url_data from schema1.table1
where
url_data Like 'abc/portfolio/%/strategy'
declare #v varchar(100) = 'abc/portfolio/*/strategy'
Select Url_data from schema1.table1 where url_data Like
replace(
case
when charindex('**',#v) > 0 then left(#v, charindex('**',#v))
else #v
end
,'*','%')
This will replace the * by % if only one * is in the variable #v or truncate the text after ** and replace ** it by %.
declare #v varchar(100) = 'abc/portfolio/*/strategy' -> abc/portfolio/%/strategy
declare #v varchar(100) = 'abc/portfolio/**/strategy' --> abc/portfolio/%

Output a database and its string

I get an error where it states invalid column 'DatabaseSQL' when I try to add a database reference into an OUTPUT statement like below:
OUTPUT [DatabaseSQL] +'.dbo.Package' 'TableName', 'PackageID', inserted.PackageId,
Core.updXMLFragment('StatusID', inserted.StatusID, Deleted.StatusID)
INTO #OutputList
If I remove the DatabaseSQL and added it as a string like OUTPUT 'Database.dbo.Package..., then it works fine, but I need the statement to actually recognise the database as well as add it as a string, just outputting it as a string alone isn't good enough. Any ideas?
You could use: DB_NAME():
OUTPUT DB_NAME() + '.dbo.Package', 'TableName', 'PackageID' ...
If you store DB name in variable use:
DECLARE #DatabaseSQL SYSNAME = QUOTENAME('name with space');
OUTPUT #DatabaseSQL + '.dbo.Package', 'TableName', 'PackageID' ...
LiveDemo

Show comma instead of point as decimal separator

I just want to get the right number format here in germany, so i need to show commas as decimal separator instead of points. But this...
DECLARE #euros money
SET #euros = 1025040.2365
SELECT CONVERT(varchar(30), #euros, 1)
Displays 1,025,040.24 instead of 1.025.040,24 (or 1025040,24). In C# it would be simple to provide the appropriate CultureInfo but how to do it in T-SQL?
Do i really need to use REPLACE? But even if, how to replace 1,025,040.24 correctly?
To provide the appropriate culture info, in SQL 2012 there is the FORMAT() function. Here's an example:
declare #f float = 123456.789;
select
[raw] = str(#f,20,3)
,[standard] = cast(format(#f, 'N', 'en-US') as varchar(20))
,[German] = cast(format(#f, 'N', 'de-DE') as varchar(20))
returns
raw |standard |German |
---------------------|-----------|-----------|
123456.789 |123,456.79 |123.456,79 |
You can also specify in the second parameter a custom format string with the same rules as for .NET.
Docs: https://msdn.microsoft.com/en-US/library/hh213505.aspx
Well, as far as I know, there are no culture-specific options for convert available.
So you can do it using replaces (yes, it looks a bit ugly...)
select
replace(replace(replace(convert(varchar(30), #euros, 1), ',', '|'), '.', ','), '|', '.')
Idea: first change comma to something, then change dot to comma, and then "something" back to dot.
DECLARE #euros money
SET #euros = 1025040.2365
SELECT REPLACE(CONVERT(varchar(30), #euros, 0), '.', ',')
should do it (at least to get 1025040,24)
You could use replace something like this:
DECLARE #euros money
SET #euros = 1025040.2365
SELECT REPLACE(REPLACE(CONVERT(varchar(30), #euros, 1),',',''),'.',',');
SQL Fiddle Demo
You can first replace thousand separator comma(,) to a Zero length string (''), and then you can replace Decimal('.') to comma(',') in the same select statement.

Resources