show data with decode function in oracle - oracle

original data (image)
I want to display my data by concatenating several columns. But the data that appears less than perfect: there is a comma behind at the end of the concatenations, like the picture shows:
Here is the query that I created in oracle 10g
select id_pegawai,
whitelist_pembayaran||decode(whitelist_pembayaran,null,null,', ')||
whitelist_pemasang||decode(whitelist_pemasang,null,null,', ')||
whitelist_jenis_iklan||decode(whitelist_jenis_iklan,null,null) as whitelist,
blacklist_pembayaran||decode(blacklist_pembayaran,null,null,', ')||
blacklist_pemasang||decode(blacklist_pemasang,null,null,', ')||
blacklist_jenis_iklan||decode(blacklist_jenis_iklan,null,null) as blacklist
from verifikator order by id_verifikator desc

so you just want to remove the comma at the end? RTRIM it.
select id_pegawai,
rtrim(whitelist_pembayaran || decode(whitelist_pembayaran, null, null, ', ') ||
whitelist_pemasang || decode(whitelist_pemasang, null, null, ', ') ||
whitelist_jenis_iklan, ',') as whitelist,
rtrim(blacklist_pembayaran || decode(blacklist_pembayaran, null, null, ', ') ||
blacklist_pemasang || decode(blacklist_pemasang, null, null, ', ') ||
blacklist_jenis_iklan, ',') as blacklist
from verifikator
order by id_verifikator desc

Related

In a CASE statement, can you store WHEN subquery result for use in the THEN output?

I have a report outputting the results of a query which was designed to provide links to a webpage:
SELECT
a,
b,
c,
'string' ||
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%URL_LINK~' || ipp_code || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY
) AS URL
FROM men_ipp
This works well, but I was asked to amend it so that if the records needed to generate the URL were missing (ie. sso_code can't be retrieved), it outputs a warning message instead of the subquery output.
Since there's always going to be a string of a set length (6 characters in this example), my solution was to create a CASE statement which is evaluating the length of the subquery output, and if the answer is greater than 6 characters it returns subquery result itself, otherwise it returns a warning message to the user. This looks like:
SELECT
a,
b,
c,
CASE
WHEN
LENGTH('string' ||
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%IPP_URL_LINK~' || (ipp_code) || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY)
) > 6
THEN
('string' ||
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%IPP_URL_LINK~' || (ipp_code) || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY)
ELSE 'warning message'
END AS URL
FROM men_ipp
The statment works fine, however the processing time is nearly doubled because it's having to process the subquery twice. I want to know if there's any way to store the result of the subquery in the WHEN, so it doesn't need to be run a second time in the THEN? eg. as a temporary variable or similar?
I've tried to declare a variable like this:
DECLARE URLLINK NVARCHAR(124);
SET URLLINK = 'string' ||
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%URL_LINK~' || ipp_code || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY
)
However this causes the query to error saying the it Encountered the symbol "https://evision.dev.uwl.tribalsits.com/urd/sits.urd/run/siw_file_load.sso?" when expecting one of the following: := . ( # % ; not null range default character
You can use NULLIF to make the result null if it is "string" (i.e., you appended nothing to it from your subquery). Then use NVL to convert to the warning message. Something like this:
SELECT
a,
b,
c,
nvl(nullif(
'string' ||
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%IPP_URL_LINK~' || (ipp_code) || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY),'string'),'warning message')
FROM men_ipp
Use a CTE.
with temp as
(SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%IPP_URL_LINK~' || (ipp_code) || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY
)
select a, b, c,
case when sso_code is null then 'warning message'
else 'string' || sso_code
end as url
from men_ipp full outer join temp on 1 = 1;
Use a sub-query:
SELECT a,
b,
c,
CASE
WHEN LENGTH(sso_code) > 6
THEN sso_code
ELSE 'warning message'
END AS URL
FROM (
SELECT a,
b,
c,
'string' ||
( SELECT sso_code
FROM men_sso
WHERE sso_parm LIKE '%IPP_URL_LINK~' || ipp_code || '%'
ORDER BY sso_cred, sso_cret
FETCH FIRST 1 ROWS ONLY ) AS sso_code
FROM men_ipp
)

Not getting multiple data for binding parameters in select statement in oracle [duplicate]

I have this query that I'm passing 2 parameters, COUNTRY_REGION parameter and COST_CENTER parameter
I have the possibility to pass both parameters at the same time COST_CENTER and COUNTRY_REGION..... Or pass one or the other... This part is OK.
You can see in the first image below
SELECT
dwg.GEOGRAPHY_ID as geographyId
,INITCAP (lower (dwc.COUNTRY_REGION)) as countryRegion
,INITCAP (lower (dwc.COUNTRY_NAME)) as countryName
,dp.PROJECT_ID as projectId
FROM
DATALAKE.DWL_GEOGRAPHIES dwg
,DATALAKE.DWB_PROJECT dp
,DATALAKE.DWL_GEOGRAPHY_COUNTRIES dwgc
,DATALAKE.DWL_COUNTRY dwc
,DATALAKE.DWB_PROJECT_FINANCIAL dpf
,DATALAKE.DWL_GOLIVE dgl
where dwg.geography_id = dp.project_geography_id
and dwg.geography_id = dwgc.geography_id
and dwc.country_id = dwgc.country_id
and dp.PROJECT_ID = dpf.PROJECT_ID
and dpf.PROJECT_ID = dgl.PROJECT_ID
and dpf.FLAG_ACTIVE = 1
and ((dp.cost_center = (:costCenter) and INITCAP (lower (dwc.COUNTRY_REGION)) = (:countryRegion))
or (:costCenter IS null and INITCAP (lower (dwc.COUNTRY_REGION)) = (:countryRegion))
or (dp.cost_center = (:costCenter) and :countryRegion IS null)
)
order by dwc.COUNTRY_REGION
But I WANT TO HAVE THE OPTION TO PASSA TWO OR MORE IN THE SAME PARAMETER as in the image below...
example:
COUNTRY_REGION: Peru, Chile, Argentina
or
COST_CENTER : 10500, 1000, ... , ....
I would like help, I've tried several things and I can't proceed, thank you very much.
You cannot pass multiple values with a single bind variable.
What you can do is pass in a single string that contains a delimited list and match a sub-string of the list to the value:
SELECT *
FROM table_name
WHERE ', ' || :country_region_list || ', ' LIKE '%, ' || country_region || ', %'
OR ', ' || :cost_centre_list || ', ' LIKE '%, ' || cost_centre || ', %'
Which would make your query:
SELECT dwg.GEOGRAPHY_ID as geographyId
, INITCAP(dwc.COUNTRY_REGION) as countryRegion
, INITCAP(dwc.COUNTRY_NAME) as countryName
, dp.PROJECT_ID as projectId
FROM DATALAKE.DWL_GEOGRAPHIES dwg
INNER JOIN DATALAKE.DWB_PROJECT dp
ON (dwg.geography_id = dp.project_geography_id)
INNER JOIN DATALAKE.DWL_GEOGRAPHY_COUNTRIES dwgc
ON (dwg.geography_id = dwgc.geography_id)
INNER JOIN DATALAKE.DWL_COUNTRY dwc
ON (dwc.country_id = dwgc.country_id)
INNER JOIN DATALAKE.DWB_PROJECT_FINANCIAL dpf
ON (dp.PROJECT_ID = dpf.PROJECT_ID)
INNER JOIN DATALAKE.DWL_GOLIVE dgl
ON (dpf.PROJECT_ID = dgl.PROJECT_ID)
WHERE dpf.FLAG_ACTIVE = 1
AND (
', ' || :costCenter || ', ' LIKE '%, ' || dp.cost_center || ', %'
OR :costCenter IS null
)
AND (
', ' || :countryRegion || ', '
LIKE '%, ' || INITCAP(dwc.COUNTRY_REGION) || ', %'
OR :countryRegion IS null
)
AND (:costCenter IS NOT NULL OR :countryRegion IS NOT NULL)
order by dwc.COUNTRY_REGION

ORA-01427: single-row Subquery Returns More Than One Row for Update

Hi I am trying to execute but getting error single row subquery returns more than one row.
update upld_mktprice
set (upld_mktprice.orig_security, upld_mktprice.stk_exch, upld_mktprice.stk_group, upld_mktprice.instr_type) =
(select security.security,nvl(upld_mktprice.stk_exch,
nvl(security.stk_exch,'DIRECT')),
security.stk_group,
decode(upld_mktprice.source,'FOREX','X','S') as instr_type -- HLAMUAT-1457146: Passing DIRECT as a default value for HLAM. confirmed by Dheeren/Prasanth.
from v_security_all security
where upld_mktprice.security = Decode(security.asset_type,'OPT',security.stk_sec_id||' '||substr(security.security,instrb(security.security, ' ', 1,1)+3, length(security.security)),security.stk_sec_id)
and rectype = 'L'),
upld_mktprice.currency = nvl(upld_mktprice.currency,''),
upld_mktprice.value_date = nvl(upld_mktprice.value_date,''),
upld_mktprice.amc_code = 'AMC'
Where exists (select 1
from v_security_all security
where upld_mktprice.security = Decode(security.asset_type,'OPT',security.stk_sec_id||' '||substr(security.security,instrb(security.security, ' ', 1,1)+3, length(security.security)),security.stk_sec_id)
and rectype = 'L')
and upld_mktprice.orig_security is null
and upld_mktprice.user_id = 'SRINIVAS'
and upld_mktprice.source = 'MKTPRICEMAN';
I think the error pretty much speaks for itself. The portion of your query below is returning more than one row. There is no way for us to validate because we do not have the data that you have. It might also be a bit easier to troubleshoot if you used table aliases in your update statement.
(SELECT security.security,
NVL (upld_mktprice.stk_exch, NVL (security.stk_exch, 'DIRECT')),
security.stk_group,
DECODE (upld_mktprice.source, 'FOREX', 'X', 'S') AS instr_type -- HLAMUAT-1457146: Passing DIRECT as a default value for HLAM. confirmed by Dheeren/Prasanth.
FROM v_security_all security
WHERE upld_mktprice.security =
DECODE (security.asset_type,
'OPT', security.stk_sec_id
|| ' '
|| SUBSTR (security.security,
INSTRB (security.security,
' ',
1,
1)
+ 3,
LENGTH (security.security)),
security.stk_sec_id)
AND rectype = 'L')

Oracle function to select multiple rows in a single row not working

I am loading a file into a staging record using Application Engine. when ever there is blank in BU,Deptid etc... I have to capture what all columns are blank and update error text field with those values.
UPDATE SYSADM.PS_VI_EMP_TS SET ERR_TEXT =
SELECT ERROR FROM (SELECT * FROM (
SELECT CASE WHEN BUSINESS_UNIT = ' ' THEN 'BUSINESS_UNIT IS NULL' ELSE ' ' END AS ERROR FROM SYSADM.PS_VI_EMP_TS WHERE USERID='JCOOPER' AND ACTION = 'E' AND PROCESS_INSTANCE = '7852429'
UNION
SELECT CASE WHEN DEPTID = ' ' THEN 'DEPTID IS NULL' ELSE ' ' END AS ERROR FROM SYSADM.PS_VI_EMP_TS WHERE USERID='JCOOPER' AND ACTION = 'E' AND PROCESS_INSTANCE = '9852429'
UNION
SELECT CASE WHEN PROJECT_ID =' ' THEN 'PROJECT_ID IS NULL' ELSE ' ' END AS ERROR FROM SYSADM.PS_VI_EMP_TS WHERE USERID='JCOOPER' AND ACTION = 'E' AND PROCESS_INSTANCE = '9852429'
)) WHERE ERROR <> ' '
WHERE USERID='JCOOPER' AND ACTION = 'E' AND PROCESS_INSTANCE = '9852429'
The above script results as below.
ERROR
BUSINESS_UNIT IS NULL
DEPTID IS NULL
I want the result as below.
ERROR
BUSINESS_UNIT IS NULL,DEPTID IS NULL
I am using ListAgg function but facing errors as below.Any help would be great.
SELECT LISTAGG(BUSINESS_UNIT, ';') WITHIN GROUP(ORDER BY USERID)
FROM SYSADM.PS_VI_EMP_TS WHERE USERID='JCOOPER'
GROUP BY BUSINESS_UNIT
Facing the error:
ORA-00923: FROM keyword not found where expected
00923. 00000 - "FROM keyword not found where expected"
*Cause:
*Action:
Error at Line: 47 Column: 43
You overcomplicated things. You don't need two unions and listagg at all. Simple use concatenation of case... when, write your select like here:
select case business_unit when ' ' then 'BUSINESS_UNIT IS NULL; ' end ||
case deptid when ' ' then 'DEPTID IS NULL; ' end ||
case project_id when ' ' then 'PROJECT_ID IS NULL; ' end as error
from ps_vi_emp_ts
where userid = 'JCOOPER' and action = 'E' and process_instance = '9852429'
demo
If your table has primary key then use it for update. Otherwise you can use merge with rowid. Or do it the way you did it if it worked for you, especially if there is only one row meeting criteria.

SSRS 2005 - Omitting Records

I have a stored proc that has several parameters. Most of them allow for multiple selections in a drop-down menu. They are: vOwner, vFunction, vSite, vStatus (all multiple selections allowed and the "Select All" is also enabled), and then vStartDate and vEndDate.
For some reason, when I choose "Select All" for every parameter, SSRS cuts off some of the records. It seems to report everything except records for the very last "owner." I'm looking for a clue as to why this might be happening. It happens when I select just one date's worth of data. It's as though that last owner isn't even being picked up as part of the data set.
Where SSRS is concerned, the settings are fairly simple. I have a data set that references the stored procedure (below), and one for each of the lookup tables i have (function, status, etc.) Any help is appreciated. Let me know if other information is needed. Thanks!
Stored Procedure:
#vOwner varchar(1000) = NULL,
#vFunction varchar(1000) = NULL,
#vStatus varchar(1000) = NULL,
#vLocation varchar(1000) = NULL,
#vBeginDate datetime = NULL,
#vEndDate datetime = NULL
AS
BEGIN
--Allow for multiple owners, functions, etc. to be selected in SSRS.
Select #vOwner = ', ' + #vOwner + ', '
create table #Owner
(
Owner varchar(1000)
)
Insert Into #Owner
Select ManagerLastName + ', ' + ManagerFirstName As Owner
From Managers
Where #vOwner Like '%, ' + ManagerLastName + ', ' + ManagerFirstName + ', %'
Group By ManagerLastName, ManagerFirstName
--Function
Select #vFunction = ', ' + #vFunction + ', '
create table #Function
(
Functions varchar(1000)
)
Insert Into #Function
Select Functions
From Functions
Where #vFunction Like '%, ' + Functions + ', %'
Group By Functions
--Status
Select #vStatus = ', ' + #vStatus + ', '
create table #Status
(
IssueStatus varchar(1000)
)
Insert Into #Status
Select IssueStatus
From IssueStatus
Where #vStatus Like '%, ' + IssueStatus + ', %'
Group By IssueStatus
--Sites
Select #vLocation = ', ' + #vLocation + ', '
create table #Sites
(
siteName varchar(1000)
)
Insert Into #Sites
Select siteName
From Sites
Where #vLocation Like '%, ' + siteName + ', %'
Group By siteName
Select
recID,
siteName
functions
From issueInput
Where
#vFunction Like '%, ' + functions + ', %'
And #vOwner Like '%, ' + ManagerLastName + ', ' + ManagerFirstName + ', %'
And #vStatus Like '%, ' + IssueStatus + ', %'
And #vLocation Like '%, ' + SiteName + ', %'
And (#vBeginDate Is Null Or #vBeginDate = 0 Or #vBeginDate <= Cast(Convert(varchar,(OpenDate),101) As datetime))
And (#vEndDate Is Null Or #vEndDate = 0 Or #vEndDate >= Cast(Convert(varchar,(OpenDate),101) As datetime))
Order by OpenDate
END
Is there a reason you using a stored procedure? It's possible to do what you want, but passing multiple values on a single parameter isn't natively supported by SQL Server. If you want to do this, you have to do some hack, which from the looks of your SQL, you have impelmented a work around.
If you embed the query in the rdl file, you can simply have an IN clause (i.e. IN(#vOwner)) and SSRS will insert the values into the query in a proper way such that it has the expected behavior. This way you are relying on something that was designed to work instead of having to work around a known limitation.
Looks like it wasn't a flaw in SSRS at all. After testing it out more in SSMS, I discovered that it was only the owner value that was being cut off at the end. I increased the #vOwner parameter from varchar(1000) to varchar(2000) and it is working fine now. I was simply passing too many characters into that parameter and it was getting truncated. Problem solved. Thanks to billinkc for that light bulb!

Resources