Fetch email address from NVARCHAR2 DATATYPE - sql

I have a table in which there is a column of NVARCHAR2 datatype which holds a string.
The string contains some Email Ids which I require to fetch in a comma separated manner.
Below is the test data --
create table nvarchar2_email (email_reject nvarchar2(1000));
insert into nvarchar2_email values ('com.wm.app.b2b.server.ServiceException: javax.mail.SendFailedException: Invalid Addresses; nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <manoj.dalai#gmail.com>: Recipient address rejected: User unknown in virtual alias table;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <santoshi.k#gmail.com>: Recipient address rejected: User unknown in virtual alias table
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <biswajit-kumar.p#gmail.com>: Recipient address rejected: User unknown in virtual alias table');
insert into nvarchar2_email values ('com.wm.app.b2b.server.ServiceException: javax.mail.SendFailedException: Invalid Addresses; nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <manoj.dalai#gmail.com>: Recipient address rejected: User unknown in virtual alias table;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 <santoshi.k#gmail.com>: Recipient address rejected: User unknown in virtual alias table');
I am trying to use the below SQL but it is repeating the Email Ids !!
select email_rejetc, listagg(REGEXP_substr (email_rejetc,'[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}', 1,level), ',') within group (order by email_rejetc) invalid_email
from nvarchar2_email
connect by level <= REGEXP_count (email_rejetc,'[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}')
group by EMAIL_REJETC
Here the required output is like
manoj.dalai#gmail.com,santosh.k#gmail.com,biswajit-kumar#gmail.com
Number of emails can VARY in different rows of the table;
My DB is :
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

select (select listagg (regexp_substr(cast(e.email_reject as varchar2(1000)),'<(.*?#.*?)>',1,level,'',1),',')
within group (order by e.email_reject)
from dual
connect by level <= regexp_count (e.email_reject,'<.*?#.*?>')
) as emails
from nvarchar2_email e
;
P.s.
There seem to be an issue with regexp_substr and nvarchar that causes each character in the result to be preceded by \0.
Tested on Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

According to your example, it would appear that the e-mail address is always presented as <aaaa#bbbb>, meaning a <, a string with a # in the middle, and a > sign.
You could try something like this (cannot check syntax, so you might need to do some tests):
SUBSTR(<input string> ,
INSTR(<input string>,'<') + 1 ,
(INSTR(<input string>,'>') - INSTR(<input string>,'<') - 2
) ;
This will yield the FIRST e-mail address within the string. You may use the same concept (providing a string without the first section that contains the first e-mail address) in a loop to extract additional addresses within the same string.
I can't see a way to do this through a single "SELECT" statement because each string may have several (and not all string the same number of) addresses.
One option to investigate is to implement a recursive select (Oracle supports this), but it will be much more complex.
Personally, I would go with the approach suggested above.

Related

Postgresql query fo find IP address

I'm trying to find an IP address that match a range of hosts (172.24.12.???), but none of the following queries are working:
select * from pg_catalog.pg_stat_activity
--where client_addr <> E'(?|172\.24\.12\.)'::inet;
--where client_addr <> E'(://|^)172\\.24\\.12\\.[0-9]'::inet
I'm getting two different errors.
SQL Error [22P02]: ERROR: invalid input syntax for type inet: "(?|172.24.12.)" and
SQL Error [22P02]: ERROR: invalid input syntax for type inet: "(^)172.24.12.[0-9]"
What Am I doing wrong here. Thanks!
PostgreSQL has native utilities to handle IP addresses, you don't need to use string manipulation as workaround:
WHERE client_addr << '172.24.12/24'
Demo code:
WITH fake_pg_stat_activity (client_addr) AS (
SELECT inet '172.24.12.20'
UNION ALL SELECT inet '192.168.0.1'
)
SELECT *, CASE WHEN client_addr << '172.24.12/24' THEN TRUE ELSE FALSE END AS belongs_to_subnet
FROM fake_pg_stat_activity;
To answer this, I did the following (all of the code below is available on the fiddle here):
CREATE TABLE test
(
IP INET
);
and
INSERT INTO test VALUES
('134.34.34.34'::INET),
('172.24.12.20'::INET);
Now, you appear to have your IP addresses as strings. This is not the best idea - it's always best to use the appropriate data type (operators, comparisons, sorting, indexing, correct values enforced automatically), but in this case, we'll just have to use strings.
As pointed out by #ÁlvaroGonzález, this works nicely with IP addresses:
SELECT
*
FROM test
WHERE ip <<= '172.24.12/24'::INET;
Result:
ip
172.24.12.20
We'll just have to use the PostgreSQL cast operator (::) to convert these to strings as follows:
SELECT
ip
FROM test
WHERE ip::TEXT ~ '172\.24\.12\.[0-2]{1}[0-9]{1,2}'
Result:
ip
172.24.12.20
The regex above isn't the best - you could spend all day searching for regexes - for example this:
SELECT
ip
FROM test
WHERE ip::TEXT ~ '172\.24\.12\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
will also work and is more thorough. It's up to you to choose which regex covers your needs.

Openfire ORA-00907: Missing right parenthesis

I have the following problem retrieving messages from the OpenFire Monitoring Service plugin. I discovered that the error is due to an incorrect query in the database but I still cannot detect the error for which the query is not working correctly.
SELECT
fromjid,
fromjidresource,
tojid,
tojidresource,
sentdate,
body,
stanza,
messageid,
barejid
FROM
(
SELECT
DISTINCT ofmessagearchive.fromjid,
ofmessagearchive.fromjidresource,
ofmessagearchive.tojid,
ofmessagearchive.tojidresource,
ofmessagearchive.sentdate,
ofmessagearchive.body,
ofmessagearchive.stanza,
ofmessagearchive.messageid,
ofconparticipant.barejid
FROM
ofmessagearchive
INNER JOIN ofconparticipant ON ofmessagearchive.conversationid =
ofconparticipant.conversationid
WHERE
(
ofmessagearchive.stanza IS NOT NULL
OR ofmessagearchive.body IS NOT NULL
)
AND ofmessagearchive.messageid IS NOT NULL
AND ofmessagearchive.sentdate >= 0
AND ofmessagearchive.sentdate <= 1602748770287
AND ofconparticipant.barejid = 'usuario3#192.168.0.79'
AND (
ofmessagearchive.tojid = 'usuario4#192.168.0.79'
OR ofmessagearchive.fromjid = 'usuario3#192.168.0.79'
)
ORDER BY
ofmessagearchive.sentdate DESC
LIMIT
100
) AS part
ORDER BY
sentdate
I get an error when doing the following query
ORA-00907: missing right parenthesis
Command line error:32 Column: 9
There is no LIMIT keyword available in Oracle and if you are using Oracle 12c you can use FETCH FIRST 100 ROWS ONLY instead of it.
You cannot use AS to give alias to the sub query and it is not recognised by Oracle. So either you can remove the alias completely as you are not using it anywhere or just remove the AS and keep the alias name part only which should be fine.
Here is a good SO link about the Oracle limiting result set and you can always look into other sites available such as Oracle base or the official document as well. For 11g solution you have to use row_number

Apex parse error when creating SQL query with sql function

I have the following function:
CREATE OR REPLACE FUNCTION calc_a(BIDoctor number) RETURN number
IS
num_a number;
BEGIN
select count(NAppoint)
into num_a
from Appointment a
where BIDoctor = a.BIDoctor;
RETURN num_a;
END calc_a;
What we want is adding a column to a report that shows us the number of appointments that doc have.
select a.BIdoctor "NUM_ALUNO",
a.NameP "Nome",
a.Address "Local",
a.Salary "salary",
a.Phone "phone",
a.NumberService "Curso",
c.BIdoctor "bi",
calc_media(a.BIdoctor) "consultas"
FROM "#OWNER#"."v_Doctor" a, "#OWNER#"."Appointment" c
WHERE a.BIdoctor = c.BIdoctor;
and we got this when we are writing the region source on apex.
But it shows a parse error, I was looking for this about 2 hours and nothing.
Apex shows me this:
PARSE ERROR ON THE FOLLOWING QUERY
This is probably because of all your double quotes, you seem to have randomly cased everything. Double quotes indicate that you're using quoted identifiers, i.e. the object/column must be created with that exact name - "Hi" is not the same as "hi". Judging by your function get rid of all the double quotes - you don't seem to need them.
More generally don't use quoted identifiers. Ever. They cause far more trouble then they're worth. You'll know when you want to use them in the future, if it ever becomes necessary.
There are a few more problems with your SELECT statement.
You're using implicit joins. Explicit joins were added in SQL-92; it's time to start using them - for your future career where you might interact with other RDBMS if nothing else.
There's absolutely no need for your function; you can use the analytic function, COUNT() instead.
Your aliases are a bit wonky - why does a refer to doctors and c to appointments?
Putting all of this together you get:
select d.bidoctor as num_aluno
, d.namep as nome
, d.address as local
, d.salary as salary
, d.phone as phone
, d.numberservice as curso
, a.bidoctor as bi
, count(nappoint) over (partition by a.bidoctor) as consultas
from #owner#.v_doctor a
join #owner#.appointment c
on d.bidoctor = a.bidoctor;
I'm guessing at what the primary keys of APPOINTMENT and V_DOCTOR are but I'm hoping they're NAPPOINT and BIDOCTOR respectively.
Incidentally, your function will never have returned the correct result because you haven't limited the scope of the parameter in your query; you would have just counted the number of records in APPOINTMENT. When you're naming parameters the same as columns in a table you have to explicitly limit the scope to the parameter in any queries you write, for instance:
select count(nappoint) into num_a
from appointment a
where calc_a.bidoctor = a.bidoctor; -- HERE

T-SQL capturing Linked server name as a result column

How can I capture the (linked) server (in this case Morpheus) name as a column of the result. I do not want to define the Server name in the query itself.
exec("
select
COMNO
,T$CPLS ""Catalog""
,T$CUNO ""Customer ID.""
,T$CPGS ""Price Group""
,T$ITEM ""Item Code""
,T$UPCD UPC
,T$DSCA ""Description""
,T$WGHT ""Weight""
,T$SHIP ""Shipping Indicator""
,nvl(T$STDT,to_char(sysdate,'YYYY-MM-DD')) ""From""
,nvl(case T$TDAT
when '4712-01-01' then ' '
when null then ' '
else t$tdat
end,' ') ""To""
,nvl(t$qanp,99999999) ""Qty.""
,T$PRIC ""List Price""
,T$DISC ""Discount""
,to_char(round(t$pric * (1-t$disc/100),2),99999.99) ""Net""
,Source ""Source""
from Table(edi.ftCompositCatalog(?,?,?)) --where trim(t$item)='105188-041'
order by Source,t$cpgs,t$item",'010','145','000164') at morpheus
If, when running your query, you already know what linked server you are pointing to, then just include that as a string literal in your result:
exec("
select
'morpheus' ""Server Name""
,T$CPLS ""CATALOG""
...
Even if the linked server name is being stored in a variable, you can do this easily since you're building your query string dynamically.
If, as you say, you don't want to define it as a string literal, here is a normal way to get the host (server) name in Oracle:
SELECT SYS_CONTEXT ('USERENV', 'SERVER_HOST') FROM DUAL;
If you want to embed this as a subquery or inline view in your query, I think it would work.
*Please note that some organizations & dba's do not want you to know anything about the backend environment for security reasons, but assuming you have no roadblock there, this should work.

DB2 query error during the retrieval of a CLOB field

From Java I am doing the following query on DB2:
SELECT * FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
The field TRANSACTION_ID is a VARCHAR of length 32. I set the parameter in the preparedStatement using the setString method.
I get the error:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=63, DRIVER=3.59.81
at com.ibm.db2.jcc.am.dd.a(dd.java:676)
at com.ibm.db2.jcc.am.dd.a(dd.java:60)
at com.ibm.db2.jcc.am.dd.a(dd.java:127)
at com.ibm.db2.jcc.am.bn.c(bn.java:2546)
at com.ibm.db2.jcc.am.bn.d(bn.java:2534)
at com.ibm.db2.jcc.am.bn.a(bn.java:2026)
at com.ibm.db2.jcc.t4.cb.g(cb.java:140)
at com.ibm.db2.jcc.t4.cb.a(cb.java:40)
at com.ibm.db2.jcc.t4.q.a(q.java:32)
at com.ibm.db2.jcc.t4.rb.i(rb.java:135)
at com.ibm.db2.jcc.am.bn.gb(bn.java:1997)
at com.ibm.db2.jcc.am.cn.pc(cn.java:3009)
at com.ibm.db2.jcc.am.cn.b(cn.java:3786)
at com.ibm.db2.jcc.am.cn.bc(cn.java:678)
at com.ibm.db2.jcc.am.cn.executeQuery(cn.java:652)
Where the sqstate means "Capability is not supported by this version of the DB2 application requester, DB2 application server, or the combination of the two." But I don't use any strange functionality.
I have tried using an squ client the query:
SELECT * FROM PRV_PRE_ACTIVATION where transaction_id='A'
And it goes ok.
What is the cause of the problem?
UPDATE: The code where the statement is prepared:
s = con.prepareStatement(sSQL,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Try changing to a specified list of columns in the select list -- my guess is you have a user defined column type (or some other type) which is not supported by your driver. For example, does the statement
SELECT TRANSACTION_ID FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
work? If so then start adding columns in and you will find the problem column.
I've came across this problem lately, and after some searching on web, I've came across this link:
DB2 SQL error: SQLCODE: -270, SQLSTATE: 42997, SQLERRMC: 63
, which specifies this:
A column with a LOB type, distinct type on a LOB type, or
structured type cannot be specified in the select-list of an
insensitive scrollable cursor.
With help from an colleague, we came to this conclusion:
1, Q: When will you get this "SQLCODE=-204, SQLSTATE=42704" exception?
A: When a scrollable PreparedStatement is prepared & executed, yet there are [B|C]LOB fields exist in the select list. e.g.:
String strQuery = "SELECT NUMBER_FIELD, CHAR_FIELD, CLOB_FIELD FROM TABLE_NAME WHERE CONDITION IS TRUE;"
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, REsultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(strQuery); //and this exception will be thrown here
2, Q: So what's the solution if we want to get rid of it when [B|C]LOB fields are queried?
A: Try to use ResultSet.TYPE_FORWARD_ONLY while creating the query statement.e.g.:
stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
Or simply try this one:
stmt = conn.createStatement();
Note that the same rules apply to conn.prepareStatement() too. You may refer to Java API doc for more information.