I have org_name, add_line1 , add_line2, add_line3 which i have put on different lines by using
(RTRIM(org_name) || CHR(32) || NVL2(RTRIM(org_name), CHR(32) || '\line' || CHR(32), '') ||
RTRIM(add_line1) || CHR(32) || NVL2(RTRIM(add_line1), CHR(32) || '\line' || CHR(32), '') ||
RTRIM(add_line2) || CHR(32) || NVL2(RTRIM(add_line2), CHR(32) || '\line' || CHR(32), '') ||
RTRIM(add_line3) || CHR(32) || NVL2(RTRIM(add_line3), CHR(32) || '\line' || CHR(32), '') || )AS "POSTAL_ADDRESS"
The problem is sometimes org_name is same as add_line1 meaning in the output I am getting the name twice on lines 1 and 2.
What I can't figure out is how to show name once if line output is same as line2 output.
Can someone please help me on this?
a case-insensitive and having no space problem comparison might be made by using regexp_like() and trim() functions together :
case when regexp_like(trim(org_name),trim(add_line1),'i')
then
org_name
else add_line1
end as org_name
or you may try within concatenation of POSTAL ADDRESS string as
select line_no, case when regexp_like(trim(org_name),trim(add_line1),'i') then
rtrim(org_name) || chr(32) || nvl2(rtrim(org_name), chr(32) || '\line' || chr(32), '')
else
rtrim(org_name) || chr(32) || nvl2(rtrim(org_name), chr(32) || '\line' || chr(32), '') ||
rtrim(add_line1)|| chr(32) || nvl2(rtrim(add_line1), chr(32)|| '\line' || chr(32), ''
)
end as "POSTAL_ADDRESS"
from tab
Demo
Using CASE (or DECODE), e.g.
case when org_name <> add_line1 then <value you want to return)
else null
end
Related
I tried searching for an answer and found none.
I would love to make my output evenly even if the length of the article is different for each article.
this is what I have when the length are different
This is the code for the people intersted to look at
set serverout ON format WORD_WRAPPED;
CREATE OR REPLACE PROCEDURE imprimeFacture IS
CURSOR c_facture IS
SELECT
customer.contact as c_contact,
customer.address as c_address,
customer.city as c_city,
customer.state as C_state,
customer.zip as c_zip,
customer.phone as c_phone,
salesman.nom as s_nom,
salesman.address as s_address,
salesman.city as s_city,
salesman.state as s_state,
salesman.zip as s_zip,
salesman.phone as s_phone,
invoices.ino as i_ino,
invoices.idate as i_date,
detail.qty as d_qty,
parts.descript as p_description,
detail.price as d_prix,
detail.ltotal as d_prixTotal,
(
SELECT
round(SUM(detail.ltotal), 2)
FROM
detail
WHERE
detail.ino = 1054
) AS totalfacture,
(
SELECT
round(SUM(detail.ltotal * 0.15), 2)
FROM
detail
WHERE
detail.ino = 1054
) AS taxe,
(
SELECT
round(SUM(detail.ltotal * 0.15 + detail.ltotal), 2)
FROM
detail
WHERE
detail.ino = 1054
) AS totalavectaxe
FROM
invoices
JOIN detail ON detail.ino = invoices.ino
JOIN parts ON parts.pno = detail.pno
JOIN customer ON customer.cno = invoices.cno
JOIN salesman ON salesman.salesman = invoices.salesman
WHERE
invoices.ino = 1054;
rec_facture c_facture%rowtype;
fictifAvantBoucle NUMBER := 0;
BEGIN
open c_facture;
loop
FETCH c_facture into rec_facture;
exit when c_facture%notfound;
if fictifAvantBoucle = 0 then
dbms_output.put_line('Facture numéro: ' || rec_facture.i_ino || chr(10) || 'Date de facturation (Y/M/D): ' || rec_facture.i_date --section Facture
|| chr(10) || chr(10) || 'Vendu par ' || chr(10) || rec_facture.s_nom || chr(10) || 'Téléphone: ' || rec_facture.s_phone || chr(10) --section vendeur
|| 'Address: ' || rec_facture.s_address || chr(10)
|| 'Ville: ' || rec_facture.s_city || chr(10) || 'État: ' || rec_facture.s_state || chr(10) || 'ZIP: ' || rec_facture.s_zip
|| chr(10) || chr(10) || 'Facturé à ' || chr(10) || rec_facture.c_contact || chr(10) || 'Téléphone: ' || rec_facture.c_phone || chr(10) --section client
|| 'Address: ' || rec_facture.c_address
|| chr(10) || 'Ville: ' || rec_facture.c_city || chr(10) || 'État: ' || rec_facture.c_state || chr(10) || 'ZIP: ' || rec_facture.c_zip || chr(10)
|| chr(10) || '---------------------------------------------------------------------------------------------------------------------------' --section facture Article
|| chr(10) || 'Qty' || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || 'Article' || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9)
|| 'Prix unitaire' || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || 'Montant total' || chr(10)
|| '---------------------------------------------------------------------------------------------------------------------------');
fictifAvantBoucle := fictifAvantBoucle + 1;
end if;
dbms_output.put_line(rec_facture.d_qty || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || rec_facture.p_description || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9)
|| rec_facture.d_prix || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || chr(9) || rec_facture.d_prixTotal);
end loop;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no data found');
END;
BEGIN
imprimeFacture();
END;
Change your output line to something like
DBMS_OUTPUT.PUT_LINE(LPAD(rec_facture.d_qty, 3)) || -- d_qty : 3 characters
RPAD(' ', 21) || -- blanks
RPAD(rec_facture.p_description, 29) || -- p_description : 29 chars
LPAD(rec_facture.d_prix, 13) || -- d_prix : 13 chars
RPAD(' ', 23) || -- blanks
LPAD(rec_facture.d_prixTotal, 13)); -- d_prixTotal : 13 chars
How do I change my select statement so that the following will return spaces between the concatenated columns?
The current query is similar to:
SELECT
address_line1 || address_line2 || address_line3 || address_line4 || city || state || county || province || country || zip as address
FROM
table
Many thanks
Just add space characters in between the fields:
SELECT
address_line1 || ' ' || address_line2 || ' ' || address_line3 || ' ' ||
address_line4 || ' ' || city || ' ' || state || ' ' || county || ' ' ||
province || ' ' || country || ' ' || zip AS address
FROM yourTable;
I'm wondering if it is possibly to complete a string replace on a joined SQL statement. For example, my query is:
SELECT (SITE_NAME || ', ' || LOT_NUMBER || ' ' || UNIT_TYPE || ' ' || LEVEL_NUMBER
|| ' ' || UNIT_NUMBER || ' ' || ROAD_NUMBER_1 || ' ' || ROAD_NUMBER_2 || ' ' || ROAD_NAME
|| ' ' || ROAD_TYPE || ' ' || ROAD_SUFFIX || ', ' || SUBURB || ', ' || STATE) AS address
FROM ADDRESS_LOOKUP_TOOL
WHERE ADD_ID = :P1_ADD_ID;
This statement works perfectly.... providing every single address field is populated. If only some sections are populated (i.e. there is no site name, or road suffix), there are additional commas or spaces.
Here is an example of a good select:
House of Dom, Lot 1 Suite 4 4D 119 Fake St South, Domtopia, QLD
Here is an example of a flawed select:
, Lot 1 Suite 4 4D 119 Fake St , Domtopia, QLD
Is it possibly to do a string replace on the alias where I could say, for example replace(address, ' ,', ',') (Where "space comma" just becomes "comma"), or is there a better way I should be structuring my select to pick this up in one go?
An additional note: This is all being completed with in Oracle's Application Express (ApEx) if this makes a difference.
I am very new to SQL, so I apologise in advance if I ask any basic follow up questions!
Thank you!
Dominic
You don't need to do it on the alias. Just do it on the expression itself.
SELECT REPLACE(
(SITE_NAME || ', ' || LOT_NUMBER || ' ' || UNIT_TYPE || ' ' || LEVEL_NUMBER
|| ' ' || UNIT_NUMBER || ' ' || ROAD_NUMBER_1 || ' ' || ROAD_NUMBER_2 || ' ' || ROAD_NAME
|| ' ' || ROAD_TYPE || ' ' || ROAD_SUFFIX || ', ' || SUBURB || ', ' || STATE),
' ,', ',') AS address
FROM ADDRESS_LOOKUP_TOOL
WHERE ADD_ID = :P1_ADD_ID;
I need regex to capture full "create procedure" statement.
Here is one of examples, which I used for testing my regex:
CREATE OR REPLACE PROCEDURE sp_for_comp (P_VARNAME IN VARCHAR2, P_VALUE IN OUT NUMBER)
as
v_if_exists NUMBER(10,0);
BEGIN
SELECT COUNT(*) INTO v_if_exists FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;
IF v_if_exists > 0
THEN
begin
SELECT VALUE INTO P_VALUE FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;
EXCEPTION
WHEN OTHERS THEN
NULL;
end;
ELSE
begin
INSERT INTO PKG_VAR VALUES(P_VARNAME, P_VALUE);
EXCEPTION
WHEN OTHERS THEN
NULL;
end;
END IF;
END;
/
Current regex:
/CREATE\s+(OR\s+REPLACE\s+)?PROCEDURE\s+(\w+)\s*\(((?!.*\bEND\b\s*(\w+\s*)?\;\s*\/).*\s*)+.+/
As for my issue: I use QRegularExpression class and program failed when I run it on large files. Also, when I run it on small file - all works correctly.
After a lot of tests on online debuggers, like regexr.com, I could not find problem in regex.
How I should change it and where are may be problems?
Try something very simple like:
CREATE(\s+OR\s+REPLACE)\s+PROCEDURE.*?END;\s*/
It just looks for the CREATE OR REPLACE PROCEDURE at the start and then the end will be END; followed by / (indicating the end of the PL/SQL block in the SQL scope) on the next line with the minimal amount between.
(Note: You will probably want to use the ni regular expression match parameters to allow . to match the newline character and to do case-insensitive matches.)
Example:
CREATE TABLE script (value ) AS
SELECT 'CREATE OR REPLACE PROCEDURE sp_for_comp (P_VARNAME IN VARCHAR2, P_VALUE IN OUT NUMBER)' || CHR(10)
|| ' as' || CHR(10)
|| ' v_if_exists NUMBER(10,0);' || CHR(10)
|| 'BEGIN' || CHR(10)
|| ' SELECT COUNT(*) INTO v_if_exists FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;' || CHR(10)
|| ' IF v_if_exists > 0' || CHR(10)
|| ' THEN' || CHR(10)
|| ' begin' || CHR(10)
|| ' SELECT VALUE INTO P_VALUE FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;' || CHR(10)
|| ' EXCEPTION' || CHR(10)
|| ' WHEN OTHERS THEN' || CHR(10)
|| ' NULL;' || CHR(10)
|| ' end;' || CHR(10)
|| 'ELSE' || CHR(10)
|| ' begin' || CHR(10)
|| ' INSERT INTO PKG_VAR VALUES(P_VARNAME, P_VALUE);' || CHR(10)
|| ' EXCEPTION' || CHR(10)
|| ' WHEN OTHERS THEN' || CHR(10)
|| ' NULL;' || CHR(10)
|| ' end;' || CHR(10)
|| ' END IF;' || CHR(10)
|| 'END;' || CHR(10)
|| '/'
FROM DUAL;
SELECT COUNT(*)
FROM script
WHERE REGEXP_LIKE( value, '^CREATE(\s+OR\s+REPLACE)\s+PROCEDURE.*?END;\s*/$', 'n' );
Outputs:
COUNT(*)
--------
1
I have a function with a loop inside a loop and I'm getting 'numeric or value error'.
sendXML CLOB;
FOR p IN (
SELECT ID, NAME, GUID FROM products
WHERE ID = IN_PROJECT_ID
)
LOOP
if p.ID is not null and p.NAME is not null then
sendXML := sendXML || '<product type="product" id="' || p.ID|| '" name="' || p.NAME || '">';
FOR t IN (
SELECT
identifier ATTR_IDENTIFIER,
label ATTR_LABEL,
CASE type
WHEN UPPER('STRING') THEN TRIM(string_value)
WHEN UPPER('NUMBER') THEN TRIM(TO_CHAR(number_value))
ELSE '' END ATTR_VALUE
FROM products_data
WHERE
product_id = p.ID AND
identifier is not null
ORDER BY identifier
)
LOOP
sendXML := sendXML || '<attribute identifier="' || t.ATTR_IDENTIFIER || '" label="'|| t.ATTR_LABEL || '">' || t.ATTR_VALUE || '</attribute>';
END LOOP;
END IF;
END LOOP;
The error
ORA-06502: PL/SQL:numeric or value error ORA-06512: at "ASM.XXXX", line 85 06502
06502. 00000 - "PL/SQL: numeric or value error%s"
throws for the line:
sendXML := sendXML || '<product type="product" id="' || p.ID|| '" name="' || p.NAME || '">';
But I found out that if I delete the last
sendXML := sendXML || '<attribute identifier="' || t.ATTR_IDENTIFIER || '" label="'|| t.ATTR_LABEL || '">' || t.ATTR_VALUE || '</attribute>';
I'm not getting any error.
Wheres the problem?
SOLUTION:
p.ID is integer and must be char... TO_CHAR(p.ID) solved my problem!
sendXML := sendXML || '<product type="product" id="' || TO_CHAR(p.ID) ||
My guess is that the string becomes larger than the maximum for varchar2 in PL/SQL.
Try the following to append text to a clob:
dbms_lob.append(sendXML, to_clob('<product type="product" id="' || p.ID|| '" name="' || p.NAME || '">'));
and the second one:
dbms_lob.append(sendXML, to_clob('<attribute identifier="' || t.ATTR_IDENTIFIER || '" label="'|| t.ATTR_LABEL || '">' || t.ATTR_VALUE || '</attribute>'));
Use quote operator like
sendXML := sendXML || q'[<attribute identifier=']' || t.ATTR_IDENTIFIER || q'[' label=']'|| t.ATTR_LABEL || q'['>]' || t.ATTR_VALUE || q'[</attribute>]';
To escape quotes. See if error persists