Remove a special character that exists between 2 characters - abap

I have the following string:
6103951001#136,00#S0#0#99999999#8000010000#10.12.2019#
31.10.2019#"MATZOURAKIS IOANNISMROA118#OSPh"#99470##APE A 54226#K
What I want is to delete the special character HORIZONTAL_TAB(#) which is between " here is the part of the string: "MATZOURAKIS IOANNISMROA118#OSPh"
How can I do?
Thanks
PS. I am using the following to upload the data from a TAB delimited text file
data: data_table type standard table of char255,
wa_data_table like line of data_table.
lv_file = p_file.
cl_gui_frontend_services=>gui_upload(
exporting
filename = lv_file
filetype = 'ASC'
changing
data_tab = data_table
Now I am doing the following in order to catch the problem
loop at data_table into wa_data_table.
find all occurrences of '"' in wa_data_table match count lv_count.
if sy-subrc = 0 and lv_count = 2.
* REPLACE ALL OCCURRENCES OF REGEX
* '(#(?=[^"]*"[^"]*(?:"[^"]*"[^"]*)*$))' IN wa_data_table WITH ' '.
split wa_data_table at '"'
into split_data1 split_data2 split_data3.
replace all occurrences of cl_abap_char_utilities=>horizontal_tab
in split_data2 with ' '.
concatenate split_data1 split_data2 split_data3
into wa_data_table.
endif.
endloop.
I think that we must handle the cl_abap_char_utilities=>horizontal_tab not with the character # but in another way.

You can use following in ABAP to find this character and replace it:
data : lv_test type string VALUE '6103951001#136,00#S0#0#99999999#8000010000#10.12.2019# 31.10.2019#"MATZOURAKIS IOANNISMROA118#OSPh"#99470##APE A 54226#K'.
REPLACE ALL OCCURRENCES OF REGEX '(#(?=[^"]*"[^"]*(?:"[^"]*"[^"]*)*$))' IN lv_test WITH ''.
write lv_test.
This is the correct solution for this problem.
replace all occurrences of regex
'(\t(?=[^"]*"[^"]*(?:"[^"]*"[^"]*)*$))'
in table data_table with ' '.
replace all occurrences of regex '["]' in table data_table with ''.

Related

Find simple position of regexp match in string in PostgreSQL

I am trying to find the first position of regexp in the string (the exact position id) to be able to delete it, but I can't find such a solution in PostgreSQL.
My query eats separators and combines strings and tries to cut only values between separators. For example, when I have a string value in a column such as:
57080*570801*157080*5708011
670811*67081*670810*670815
I tried to use:
UPDATE tab
set str = (REGEXP_REPLACE(str, '^57080*', '')
WHERE myColumn=159880;
or
UPDATE tab
set str = (REGEXP_REPLACE(str, '*57080*', '')
WHERE myColumn=159880;
or
UPDATE tab
set str = (REGEXP_REPLACE(str, '*57080$', '')
WHERE myColumn=159880;
However, this doesn't help me because after using
(REGEXP_REPLACE (str, '* 57080 *', '') I have a stuck id (e.g. 57080570801). I need to find my regexp position somehow to be able to cut only the id. After that I can always use REPLACE (string , '**', '*') which will cut out double characters or
SET str = CASE
WHEN str LIKE '*%' THEN RIGHT (str, LENGTH (str) -1)
WHEN str LIKE '% *' THEN LEFT (str, LENGTH (str) -1)
will cut the start / end characters (*). Does anyone have any idea how to easily find positions of such a regexp.
Use the “beginning of word” and “end of word” markers:
regexp_replace(str, '\m12345\M', '')

How to do a search with multiple non-obligatory Input fields?

I would like to ask how to do a basic search filtering in a selection screen that has multiple input fields which aren't required.
I tried to do it by using multiple IF statements followed by WHERE clauses which solves my current problem but its not fully correct, if i work with only a few inputs (2 at the moment, 'ID' and 'Number'), the code isn't too long, but if its over 10 or so it feel wrong to do it this way
What i tried so far was approximately like this :
IF lv_id IS INITIAL and lv_nr IS INITIAL.
SELECT * from DBase INTO TABLE Local_Table.
ELSEIF lv_id IS NOT INITIAL AND lv_nr IS INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE ID = lv_nr.
ELSEIF lv_id IS INITIAL AND lv_nr IS NOT INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE Number = lv_nr.
ELSEIF lv_id IS NOT INITIAL AND lv_nr IS NOT INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE ID = lv_id AND Number = lv_nr.
The expected result is for the search to get executed correctly by having no input or multiple non-obligatory inputs, without having to write a very long code in case the number of inputs is high.
you can use the IN Operator in your WHERE clause when you have multiple conditions.
First You need to define a Selection Table for every parameter and have to fill them or leave them empty.
types: begin of myselopt ,
sign type char1 ,
option type char2 ,
low type ... (depends on the type you want select)
high type ... ,
end of myselopt .
types : t_selopt type table of myselopt .
data: gt_selopt type t_selopt ,
gt_selopt_2 type t_selopt_2 . #needs to be defined first
if lv_id is not initial .
insert value #( sign = 'I' option = 'EQ' low = lv_id ) into table gt_selopt .
endif .
if lv_nr is not initial .
insert value #( sign = 'I' option = 'EQ' low = lv_nr ) into table gt_selopt_2 .
endif .
You have to do this for every Parameter you want to query. And your query would look like this
select * from dbaste into table local_table where id in gt_selopt
and number in gt_selopt_2 .
You can define your input fields as SELECT-OPTIONS (with optional NO INTERVALS NO-EXTENSION to mimick the look of PARAMETERS). Then just use the IN operator in your WHERE clause:
REPORT.
DATA: your_ztable TYPE your_ztable.
SELECT-OPTIONS: s_id FOR your_ztable-id NO INTERVALS NO-EXTENSION,
s_nr FOR your_ztable-number NO INTERVALS NO-EXTENSION.
AT SELECTION-SCREEN.
SELECT * FROM your_ztable
WHERE id IN #s_id
AND number IN #s_nr
INTO TABLE #DATA(local_table).
What about this approach with concatenated where conditions?
DATA:
lv_where TYPE string.
IF lv_id IS NOT INITIAL.
CONCATENATE ' AND ID' space '=' space '"' lv_id '"' INTO lv_where.
ENDIF.
IF lv_nr IS NOT INITIAL.
CONCATENATE ' AND Number' space '=' space '"' lv_nr '"' INTO lv_where.
ENDIF.
IF lv_where IS NOT INITIAL.
SHIFT lv_where By 5 PLACES. " to remove leading _AND_ (
ENDIF.
SELECT * from DBase INTO TABLE Local_Table WHERE (lv_where).

Detect \n character saved in SQLite table?

I designed a table with a column whose data contains \n character (as the separator, I used this instead of comma or anything else). It must save the \n characters OK because after loading the table into a DataTable object, I can split the values into arrays of string with the separator '\n' like this:
DataTable dt = LoadTable("myTableName");
DataRow dr = dt.Rows[0]; //suppose this row has the data with \n character.
string[] s = dr["myColumn"].ToString().Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries);//This gives result as I expect, e.g an array of 2 or 3 strings depending on what I saved before.
That means '\n' does exist in my table column. But when I tried selecting only rows which contain \n character at myColumn, it gave no rows returned, like this:
--use charindex
SELECT * FROM MyTable WHERE CHARINDEX('\n',MyColumn,0) > 0
--use like
SELECT * FROM MyTable WHERE MyColumn LIKE '%\n%'
I wonder if my queries are wrong?
I've also tested with both '\r\n' and '\r' but the result was the same.
How can I detect if the rows contain '\n' character in my table? This is required to select the rows I want (this is by my design when choosing '\n' as the separator).
Thank you very much in advance!
Since \n is the ASCII linefeed character try this:
SELECT *
FROM MyTable
WHERE MyColumn LIKE '%' || X'0A' || '%'
Sorry this is just a guess; I don't use SQLite myself.
Maybe you should just be looking for carriage returns if you arent storing the "\n" literal in the field. Something like
SELECT *
FROM table
WHERE column LIKE '%
%'
or select * from table where column like '%'+char(13)+'%' or column like '%'+char(10)+'%'
(Not sure if char(13) and 10 work for SQLite
UPDATED: Just found someone's solution here They recommend to replace the carriage returns
So if you want to replace them and strip the returns, you could
update yourtable set yourCol = replace(yourcol, '
', ' ');
The following should do it for you
SELECT *
FROM your_table
WHERE your_column LIKE '%' + CHAR(10) + '%'
If you want to test for carriage return use CHAR(13) instead or combine them.
I've found a solution myself. There is few way (with some dedicated function) to convert ascii code to symbol in SQLite at the moment (CHAR function is not support and using '\n' or '\r' directly doesn't work). But we can convert using CAST function and passing in a Hex string (specified by append X or x before the string) in SQLite like this:
-- use CHARINDEX
SELECT * FROM MyTable WHERE CHARINDEX(CAST(x'0A' AS text),MyColumn,0) > 0
-- use LIKE
SELECT * FROM MyTable WHERE MyColumn LIKE '%' || CAST(x'0A' AS text) || '%'
The Hex string '0A' is equal to 10 in ascii code (\r). I've tried with '0D' (13 or '\n') but it won't work. Maybe the \n character is turned to \r after being saved in to SQLite table.
Hope this helps others! Thanks!

LOAD DATA INFILE (*.csv) - ignore empty cells

I'm about to import a large (500 MB) *.csv file to a MySQL database.
I'm as far as that:
LOAD DATA INFILE '<file>'
REPLACE
INTO TABLE <table-name>
FIELDS
TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES ( #Header
<column-name1>,
<column-name2>,
...
);
I have a problem with one of the coluns (it's data type is int) - I get an error Message:
Error Code: 1366 Incorrect integer value: ' ' for column at row
I looked at this line in the *.csv-file. The cell that causes the error has just a whitespace inside (like this: ...; ;...).
How can I tell SQL to ignore whitespaces in this column?
As the *.csv-file is very big and I have to import even bigger ones afterwards, I'd like to avoid editing the *.csv-file; I'm looking for a SQL-solution.
Add a SET COLUMN like so:
LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, #var1)
SET column2 = #var1/100;
You need to replace the #var1/100 with an expression that handles the 'space' and convert to -Infinity or 0 or 42... not sure..
This answer was originally included in the question as an edit by #speendo; I have converted it into a proper answer.
The solution is:
LOAD DATA INFILE '<file>'
REPLACE
INTO TABLE <table-name>
FIELDS
TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES ( #Header
<column-name1>,
<column-name2>,
#var1 #the variable that causes the problem
...
)
SET <column-name-of-problematic-column> = CASE
WHEN #var1 = ' ' THEN NULL
ELSE #var1
END
;

sql prepend entries

I have some entries that are inconstant, they should be prepended by the same string.
some have numbers and other have the dollar sign and the number
so I have a syntax that finds all the entries which do not have the dollar sign
WHERE [mydata] not like '$%'
how do I add the string before each entry?
update table set mydata = '$' + mydata where [mydata] not like '$%'
The + only works in SQLServer; you may need to use the concatenate function otherwise.
If you are looking for just a select statement to return the value with a $, this will work:
Select '$' + field
from [table]
where field not like '$%'
You can run it as a case statement had you wanted both records that have a $ and those without to be returned with the $
Select case when left(field,1) = '$' then '' else '$' end + field
from [table]
where field not like '$%'
edit: Might need to convert the 'field' into a varchar for the + to work, you'll get a syntax error if the field is an int (but you have the $ spuradically in the field, so I assumed it's a varchar