i'm trying to rebuild relations in my DB. I need to "repair" some strings that are stored badly in my table named city_list.
The data:
"Berlin"
"London "
"Kijev "
"Poznan "
I used pgsql function rtrim(string text [, characters text]) in that way:
UPDATE city_list SET city_name=RTrim(city_name);
UPDATE city_list SET city_name=RTrim(city_name, ' ');
Now I have:
"Berlin"
"Londo"
"Kijev"
"Pozna"
Is there way to force rtrim to cut whole " " string from end not every single characters?
Use regexp_replace().
The trim() function's second argument is the full list of chars to be trimmed.
Related
I have a table:
create table table_name
(id varchar(255), details jsonb)
Then i need to update some array into "details"
update table_name
set details = '["firstLineSecondLine", "ThirdLineFourthLine"]'::jsonb
where id = '1';
How can i break lines between "firstLineSecondLine"?
I need thst my body be like:
"details": [
"firstLine
SecondLine",
"ThirdLine
FourthLine"
]
Any ideas?
literal newlines inside quotes in JSON are represented by \n. They are represented this way both on input and on output, so you will not able to get it to show up the way you want to other than converting to plain text, or something else.
Also, your example is invalid for another reason, it is lacking the outer curlies.
I am trying to grab variable length string from a primary string.
Example:
ABC*12*1*name name****XX*123456789~
ABC*12*1*diffname diffname****XX*234567890~
ABC*12*1*diffname2 diffname2***XX*345678901~
I need to pull out the 'name name', 'diffname diffname', 'diffname2 diffname2'
etc from the string. And then replace the ' ' between the names with an asterisk - but, I cant just insert in the first space in the string, there could be multiple names, and so I would want to insert the '*' into the second, or third space, depending on the length of the name string.
SELECT
CHARINDEX('*1*',data)+3 AS startpos,
CHARINDEX('***',data) AS Endpos,
data
from #t
where data like '%ABC*12*1*%'
This gives me a start point and end point for the variable length string. So I try:
SELECT SUBSTRING(data,CHARINDEX('*1*',data)+3,CHARINDEX('***',data) -CHARINDEX('*1*',data)+3)
FROM #t
WHERE data like '%ABC*12*1*name%'
But this gives me
name n name aa*****X
as a result set, basically starting at the start point and then running well past the end point.
What am I doing wrong?
This part is the problem :
SELECT .....-CHARINDEX('*1*',data)+3
FROM .....
WHERE .....
You want to substract with Endpos so it supposed to be written in brackets like so :
-(CHARINDEX('*1*',data)+3)
and if the brackets are removed the last part should become -3 :
-CHARINDEX('*1*',data)-3
I need to remove non-numeric characters in a column (character varying) and keep numeric values in postgresql 9.3.5.
Examples:
1) "ggg" => ""
2) "3,0 kg" => "3,0"
3) "15 kg." => "15"
4) ...
There are a few problems, some values are like:
1) "2x3,25"
2) "96+109"
3) ...
These need to remain as is (i.e when containing non-numeric characters between numeric characters - do nothing).
Using regexp_replace is more simple:
# select regexp_replace('test1234test45abc', '[^0-9]+', '', 'g');
regexp_replace
----------------
123445
(1 row)
The ^ means not, so any character that is not in the range 0-9 will be replaced with an empty string, ''.
The 'g' is a flag that means all matches will be replaced, not just the first match.
For modifying strings in PostgreSQL take a look at The String functions and operators section of the documentation. Function substring(string from pattern) uses POSIX regular expressions for pattern matching and works well for removing different characters from your string.
(Note that the VALUES clause inside the parentheses is just to provide the example material and you can replace it any SELECT statement or table that provides the data):
SELECT substring(column1 from '(([0-9]+.*)*[0-9]+)'), column1 FROM
(VALUES
('ggg'),
('3,0 kg'),
('15 kg.'),
('2x3,25'),
('96+109')
) strings
The regular expression explained in parts:
[0-9]+ - string has at least one number, example: '789'
[0-9]+.* - string has at least one number followed by something, example: '12smth'
([0-9]+.\*)* - the string similar to the previous line zero or more times, example: '12smth22smth'
(([0-9]+.\*)*[0-9]+) - the string from the previous line zero or more times and at least one number at the end, example: '12smth22smth345'
I want to convert a column of type "character varying" that has integers with commas to a regular integer column.
I want to support numbers from '1' to '10,000,000'.
I've tried to use: to_number(fieldname, '999G999G999'), but it only works if the format matches the exact length of the string.
Is there a way to do this that supports from '1' to '10,000,000'?
select replace(fieldname,',','')::numeric ;
To do it the way you originally attempted, which is not advised:
select to_number( fieldname,
regexp_replace( replace(fieldname,',','G') , '[0-9]' ,'9','g')
);
The inner replace changes commas to G. The outer replace changes numbers to 9. This does not factor in decimal or negative numbers.
You can just strip out the commas with the REPLACE() function:
CREATE TABLE Foo
(
Test NUMERIC
);
insert into Foo VALUES (REPLACE('1,234,567', ',', '')::numeric);
select * from Foo; -- Will show 1234567
You can replace the commas by an empty string as suggested, or you could use to_number with the FM prefix, so the query would look like this:
SELECT to_number(my_column, 'FM99G999G999')
There are things to take note:
When using function REPLACE("fieldName", ',', '') on a table, if there are VIEW using the TABLE, that function will not work properly. You must drop the view to use it.
Whenever I replace placeholders in the SQL query using on it surrounds the replacement with '', is there a way to prevent this?
It means I can't do things like
SQL("SELECT * FROM {table} blah").on("table" -> tabletouse)
because it wraps the table name with '' which causes an SQL syntax error.
you could certainly combine both approaches, using the format function for data you don't want to be escaped
SQL(
"""
select %s from %s
where
name = {name} and
date between {start} and {end}
order by %s
""".format(fields, table, order)
).on(
'name -> name,
'start -> startDate,
'end -> endDate
)
Just take into account that the data you are sending using the format function should NOT come from user input, otherwise it should be properly sanitized
You cannot do what you are trying. Anorm's replacement is based on PreparedStatements. Meaning all data will automatically be escaped, meaning you cannot use replacement for :
table names,
column names,
whatever operand, SQL keyword, etc.
The best you can do here is a String concatenation (and what is really a bad way in my opinion) :
SQL("SELECT * FROM " + tabletouse + " blah").as(whatever *)
PS : Checkout this question about table names in PreparedStatements.