Concat function in postgresql - sql

I have the below select statement in hive .It executes perfectely fine.
In Hive
select
COALESCE(product_name,CONCAT(CONCAT(CONCAT(TRIM(product_id),' -
'),trim(plan_code)),' - UNKNOWN')) as product_name
from table name;
I am trying to use the same select statement in POSTGRESQL and it throw me error saying "
Query execution failed
Reason:
SQL Error [42883]: ERROR: function concat(text, unknown) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
In postgresql:
select
COALESCE(product_name,CONCAT(CONCAT(CONCAT(TRIM(product_id),' -
'),trim(plan_code)),' - UNKNOWN')) as product_name
from table name;
Could some one throw some light on this ?

Instead of concat try with ||:
SELECT COALESCE(product_name,
(TRIM(product_id) || ' - ' || TRIM(plan_code) || ' - UNKNOWN')
) AS product_name
FROM tablename;
or simply a single CONCAT as:
SELECT COALESCE(product_name,
CONCAT(TRIM(product_id)::text, ' - ', TRIM(plan_code)::text, ' - UNKNOWN')
) AS product_name
FROM tablename;

You can also consider using format function:
SELECT coalesce(product_name, format('%s - %s - UNKNOWN', trim(product_id), trim(plan_code)))

Related

Append A Value To The Existing Value In SQL, facing error

I have a table in which there is a column name associated_ids with datatype as varchar2(4000). It contains a value and i need to append the new value with existing value. Using below update query:
update ncl_getafix.service_graph
set Associated_ids = Associated_ids + ',' + '95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05';
I am getting below error:
Error starting at line : 5 in command - update
ncl_getafix.service_graph set
Associated_ids=Associated_ids+','+'95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05'
Error report - ORA-01722: invalid number.
Can anyone help to debug this.
You need to use concat operator || not + as follows:
update ncl_getafix.service_graph
set Associated_ids = Associated_ids || ',' || '95d4980b-d12c-4854-97c6-bd9854f8f003'
where SERVICE_ID='075d7a58-7fad-4e1d-9822-83a2fa1a0d05';
i found the answer.
Use || symbol instead of + in query

Using variable in Oracle function

I have a variable and want to use in a query inside fuzzy function but it is giving me some syntax error or wrong result considering the var.
ORA-20000: Oracle Text error:
DRG-50901: text query parser syntax error on line 1, column 21 29902.
00000 - "error in executing ODCIIndexStart() routine"
When I replace the my_var variable in the fuzzy function with some static string it works fine but with variable it is giving me this error.
My query is as follows:
DEFINE my_var = 'Bhularam';
SELECT a.EXTERNALID_ENC,
a.EXTERNALID,
a.TELNUMBER,
a.TELAREACODE,
a.DQ_ENGLISH_NAME,
a.DQ_ARABIC_NAME,
a.NAMEFIELD_1,
a.USAGETYPE,
a.MANUAL_UPDATE_FLAG,
a.RULE_UPDATE_FLAG,
a.BUSINESS_UPDATE_FLAG,
a.EXCEL_UPDATE_FLAG
FROM (
SELECT * FROM (
SELECT dqlist.*,
score(1) AS rank
FROM dq_list_hash_full dqlist
WHERE contains(dqlist.dq_english_name
,'definescore(fuzzy(my_var, 1, 6, weight),relevance)',1) > 0
UNION
SELECT
dqlist.*,
score(1) AS rank
FROM
dq_list_hash_full dqlist
WHERE
contains(dqlist.dq_english_name,'!Bhularam',1) > 0
)
ORDER BY
rank DESC
) a
I know it is something really stupid but I am unable to get my head around it probably I am new to oracle. Please help me out.
If using sqlplus, verify what prefix character is used to identify substitution variables. Default is set to '&'.
sqlplus > show define
define "&" (hex 26)
Try using your substitution variable within your query, for example
sqlplus > define my_var='hello world!'
sqlplus > select '&my_var' from dual;
old 1: select '&my_var' from dual
new 1: select 'hello world!' from dual
'HELLOWORLD!'
--------------------------------
hello world!
For your query try (assuming define is set to '&'):
'definescore(fuzzy(&my_var, 1, 6, weight),relevance)',1)

Oracle SQL: Using CHR() function with || concatenate and join

Query below returns error
SELECT 'mailto:'|| fscp.parameter_value || '?subject=' || wfn.subject nid_subject || chr(38)
FROM apps.wf_notifications wfn, apps.fnd_svc_comp_param_vals_v fscp
WHERE fscp.component_id = :component_id
AND component_parameter_id = :param
AND wfn.item_key = :itemkey;
Error
ORA-00923: FROM keyword not found where expected
00923.00000 - "FROM keyword not found where expected"
When I remove the '|| chr(38)' at the end of the select statement, the query runs fine.
Something related to joining tables? Because the below query also works fine:
select 'Text: '||chr(39)||wfn.notification_id||chr(39) from wf_notifications wfn;
You have this in the select:
|| wfn.subject nid_subject ||
Perhaps you intend:
SELECT 'mailto:'|| fscp.parameter_value || '?subject=' || wfn.subject || nid_subject || chr(38)
----------------------------------------------------------------------^
Alex is right. The key in the question is that it works without chr(38). So, try this:
SELECT ('mailto:'|| fscp.parameter_value || '?subject=' || wfn.subject || chr(38) ) as nid_subject
Notice the use of parentheses and as to make it clear that a column alias is being defined.

Oracle : String Concatenation is too long

I have below SQL as a part of a view. In one of the schema I am getting "String Concatenation is too long" error and not able to execute the view.
Hence I tried the TO_CLOB() and now VIEW is not throwing ERROR, but it not returning the result as well it keep on running..
Please suggest....
Sql:
SELECT Iav.Item_Id Attr_Item_Id,
LISTAGG(La.Attribute_Name
||'|~|'
|| Lav.Attribute_Value
||' '
|| Lau.Attribute_Uom, '}~}') WITHIN GROUP (
ORDER BY ICA.DISP_SEQ,LA.ATTRIBUTE_NAME) AS ATTR
FROM Item_Attribute_Values Iav,
Loc_Attribute_Values Lav,
Loc_Attribute_Uoms Lau,
Loc_Attributes La,
(SELECT *
FROM Item_Classification Ic,
CATEGORY_ATTRIBUTES CA
WHERE IC.DEFAULT_CATEGORY='Y'
AND IC.TAXONOMY_TREE_ID =CA.TAXONOMY_TREE_ID
) ICA
WHERE IAV.ITEM_ID =ICA.ITEM_ID(+)
AND IAV.ATTRIBUTE_ID =ICA.ATTRIBUTE_ID(+)
AND Iav.Loc_Attribute_Id =La.Loc_Attribute_Id
AND La.Locale_Id =1
AND Iav.Loc_Attribute_Uom_Id =Lau.Loc_Attribute_Uom_Id(+)
AND Iav.Loc_Attribute_Value_Id=Lav.Loc_Attribute_Value_Id
GROUP BY Iav.Item_Id;
Error:
ORA-01489: result of string concatenation is too long
01489. 00000 - "result of string concatenation is too long"
*Cause: String concatenation result is more than the maximum size.
*Action: Make sure that the result is less than the maximum size.
You can use the COLLECT() function to aggregate the strings into a collection and then use a User-Defined function to concatenate the strings:
Oracle Setup:
CREATE TYPE stringlist IS TABLE OF VARCHAR2(4000);
/
CREATE FUNCTION concat_List(
strings IN stringlist,
delim IN VARCHAR2 DEFAULT ','
) RETURN CLOB DETERMINISTIC
IS
value CLOB;
i PLS_INTEGER;
BEGIN
IF strings IS NULL THEN
RETURN NULL;
END IF;
value := EMPTY_CLOB();
IF strings IS NOT EMPTY THEN
i := strings.FIRST;
LOOP
IF i > strings.FIRST AND delim IS NOT NULL THEN
value := value || delim;
END IF;
value := value || strings(i);
EXIT WHEN i = strings.LAST;
i := strings.NEXT(i);
END LOOP;
END IF;
RETURN value;
END;
/
Query:
SELECT Iav.Item_Id AS Attr_Item_Id,
CONCAT_LIST(
CAST(
COLLECT(
La.Attribute_Name || '|~|' || Lav.Attribute_Value ||' '|| Lau.Attribute_Uom
ORDER BY ICA.DISP_SEQ,LA.ATTRIBUTE_NAME
)
AS stringlist
),
'}~}'
) AS ATTR
FROM your_table
GROUP BY iav.item_id;
LISTAGG is limited to 4000 characters unfortunately. So you may want to use another approach to concatenate the values.
Anyway ...
It is strange to see LISTAGG which is a rather new feature combined with error-prone SQL1992 joins. I'd suggest you re-write this. Are the tables even properly joined? It looks strange that there seems to be no relation between Loc_Attributes and, say, Loc_Attribute_Values. Doesn't have Loc_Attribute_Values a Loc_Attribute_Id so an attribute value relates to an attribute? It would be hard to believe that there is no such relation.
Moreover: Is it guaranteed that your classification subquery doesn't return more than one record per attribute?
Here is your query re-written:
select
iav.item_id as attr_item_id,
listagg(la.attribute_name || '|~|' || lav.attribute_value || ' ' || lau.attribute_uom,
'}~}') within group (order by ica.disp_seq, la.attribute_name) as attr
from item_attribute_values iav
join loc_attribute_values lav
on lav.loc_attribute_value_id = iav.loc_attribute_value_id
and lav.loc_attribute_id = iav.loc_attribute_id -- <== maybe?
join loc_attributes la
on la.loc_attribute_id = lav.loc_attribute_id
and la.loc_attribute_id = lav.loc_attribute_id -- <== maybe?
and la.locale_id = 1
left join loc_attribute_uoms lau
on lau.loc_attribute_uom_id = iav.loc_attribute_uom_id
and lau.loc_attribute_id = iav.loc_attribute_id -- <== maybe?
left join
(
-- aggregation needed to get no more than one sortkey per item attribute?
select ic.item_id, ca.attribute_id, min (ca.disp_seq) as disp_seq
from item_classification ic
join category_attributes ca on ca.taxonomy_tree_id = ic.taxonomy_tree_id
where ic.default_category = 'y'
group by ic.item_id, ca.attribute_id
) ica on ica.item_id = iav.item_id and ica.attribute_id = iav.attribute_id
group by iav.item_id;
Well, you get the idea; check your keys and alter your join criteria where necessary. Maybe this gets rid of duplicates, so LISTAGG has to concatenate less attributes, and maybe the result even stays within 4000 characters.
Xquery approach.
Creating extra types or function isn't necessary.
with test_tab
as (select object_name
from all_objects
where rownum < 1000)
, aggregate_to_xml as (select xmlagg(xmlelement(val, object_name)) xmls from test_tab)
select xmlcast(xmlquery('for $row at $idx in ./*/text() return if($idx=1) then $row else concat(",",$row)'
passing aggregate_to_xml.xmls returning content) as Clob) as list_in_lob
from aggregate_to_xml;
I guess you need to write a small function to concatenate the strings into a CLOB, because even when you cast TO_CLOB() the LISTAGG at the end, this might not work.
HereĀ“s a sample-function that takes a SELECT-Statement (which MUST return only one string-column!) and a separator and returns the collected values as a CLOB:
CREATE OR REPLACE FUNCTION listAggCLob(p_stringSelect VARCHAR2
, p_separator VARCHAR2)
RETURN CLOB
AS
cur SYS_REFCURSOR;
s VARCHAR2(4000);
c CLOB;
i INTEGER;
BEGIN
dbms_lob.createtemporary(c, FALSE);
IF (p_stringSelect IS NOT NULL) THEN
OPEN cur FOR p_stringSelect;
LOOP
FETCH cur INTO s;
EXIT WHEN cur%NOTFOUND;
dbms_lob.append(c, s || p_separator);
END LOOP;
END IF;
i := length(c);
IF (i > 0) THEN
RETURN dbms_lob.substr(c,i-length(p_separator));
ELSE
RETURN NULL;
END IF;
END;
This function can be used f.e. like this:
WITH cat AS (
SELECT DISTINCT t1.category
FROM lookup t1
)
SELECT cat.category
, listAggCLob('select t2.name from lookup t2 where t2.category = ''' || cat.category || '''', '|') allcategorynames
FROM cat;

concat apostrophe to oracle sql query

Hi all I am looking for some pointers on how I can add an apostrophe to my query results on my first column.
My current query:
set verify off
set colsep "',"
set pagesize 2000
ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-YY-HH24:MI:SS';
spool /home/user/out.txt
select '[' || table1.collectdatetime as "['Date-Time",table1.cycletime as "'Time'" from table1 where interfacename='somename' and collectdatetime > (CURRENT_DATE - 1)
order by collectdatetime ASC;
Which results:
['Date-Time ','InCycleTime'
-------------------',-------------
[02-MAR-13-17:56:16', 29
What I am struglling with is getting the results to return and add an apostrophe after the [
['Date-Time ','InCycleTime'
-------------------',-------------
['02-MAR-13-17:56:16', 29
This is for an oracle 11.1.0.7 build. The data is being queried and parsed but I need to get that apostrophe issue worked out.
use this:
select '[''' || table1.collectdatetime as "['Date-Time",table1.cycletime as "'Time'" from table1 where interfacename='somename' and collectdatetime > (CURRENT_DATE - 1)
order by collectdatetime ASC;