Remove specific character from string (SQL Server 2012) - sql

I have a view from which I want to remove a specific character in one of the columns. Specifically the character 'B' from the 'Fund' column below.
I tried using the following version of TRIM
SELECT
TRIM('B' FROM [Port_Ticker]) as "Fund"
,[BENCH_Ticker] as "Index ID"
,format(cast([VALUE_DATE] as Date),'dd/MM/yyyy') as "Updat"
,([Port_Risk_Contrib] / 10000000) as "StDev Fund"
,([Active_risk_contrib] / 10000000) as "TE"
,([BENCH_RISK_CONTRIB] / 100) as "StDev BM"
FROM [DM_PORTFOLIO_ANALYSIS].[basedata].[PortfolioRiskFigures]
where [BLOCK_FACTOR] = 'Total'
and [Port_ticker] =
'B1023'
order by [VALUE_DATE] asc
Which gives me the error
Msg 156, Level 15, State 1, Line 3.
Incorrect syntax near the keyword 'FROM'.

You can use replace() to do this. In this case it will search for 'B' and replace it with an empty string -> ''. Please note that this function will replace all 'B' from this column.
SELECT
REPLACE([Port_Ticker], 'B', '') as "Fund"
,[BENCH_Ticker] as "Index ID"
,format(cast([VALUE_DATE] as Date),'dd/MM/yyyy') as "Updat"
,([Port_Risk_Contrib] / 10000000) as "StDev Fund"
,([Active_risk_contrib] / 10000000) as "TE"
,([BENCH_RISK_CONTRIB] / 100) as "StDev BM"
FROM [DM_PORTFOLIO_ANALYSIS].[basedata].[PortfolioRiskFigures]
where [BLOCK_FACTOR] = 'Total'
and [Port_ticker] = 'B1023'
order by [VALUE_DATE] asc

The Trim() function was introduced in 2017 version.
Naturally, you can't use it in older versions.
There are several ways this can be done, by using replace as M. Kanarkowski demonstrated in his answer, or any of these options:
stuff: STUFF([Port_Ticker], 1, 1, '') As "Fund",
substring: SUBSTRING([Port_Ticker], 2, LEN([Port_Ticker])) As "Fund"
Right: RIGHT([Port_Ticker], LEN([Port_Ticker])-1) As "Fund"

Related

Parsing txt file with substring

I inherited a SQL code from my previous co-worker. The script was working the last time I ran it but it returns an error when I tried it today. Surprisingly the code is working on my colleague's PC. I double-check the SQL server database and we are using the same collation, Latin1_General_CS_AS. I did many tests, changing windows system locale etc however none of them work, the error is this:
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
...
However, I couldn't get it! why it is working on one system and not on another! Does anybody has any idea or alternative solution for the substring part.
DROP TABLE IF EXISTS #VievingLive0
SELECT
ProdDay, -- date
HouseId, -- ID
CAST(SUBSTRING(RowText, 2, CHARINDEX('_', RowText, 2)-2) AS INT) AS ChannelId, -- Channel ID
CASE WHEN LEN(s.Value) = 14 THEN LEFT(s.Value, 2) ELSE STUFF(LEFT(s.Value, LEN(s.Value)-12), 3, 0, '_') END AS Individs, -- list of persons
(LEN(s.Value)-12)/2 AS CntIndiv, -- number of persons watching
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-11,2)*3600+substring(s.Value,LEN(s.Value)-9,2)*60+substring(s.Value,LEN(s.Value)-7,2), CAST(ProdDay AS DATETIME)) AS ViewFrom, -- time from
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-5 ,2)*3600+substring(s.Value,LEN(s.Value)-3,2)*60+substring(s.Value,LEN(s.Value)-1,2)+1, CAST(ProdDay AS DATETIME)) AS ViewTo -- time to
INTO #VievingLive0
FROM #All_TX4_files
CROSS APPLY STRING_SPLIT(SUBSTRING(RowText, PATINDEX('%_[A-Za-z][A-Za-z][A-Za-z0-9]%', SUBSTRING(RowText, 2, LEN(RowText)))+2, LEN(RowText)), '_') AS s -- extracting individual vieiwng statemenets from the row
WHERE LEFT(RowText, 1) = 'V' -- LIVE viewing rows
I am trying to parse this format txt:
H98500410_0
W1941.51
Pab_2467211514110343733611_W2898.81
V100_0_2_210_ab075700080859_ab081100081259_ab081700081959_ab082800083059_ab083400083559_ab110600110959_ab111300111459_ab113500115059_ab115300120259_ab120300120359_ab120400123059_ab123100123559_ab124800125359_ab173200173259_ab191200191359_ab191600191759

In memory queries using SQL Server

I'm afraid that even though I am using CTE's in my query, that maybe, behind the scenes, a lot of disk caching is going on -- so it may as well not be using CTE's.
The whole point of using CTE's was that my original query code was way too slow, and would eventually get a transport level error and crash.
Well, it's still too slow. Maybe even slower. I don't know yet.
Is there a way to tell SQL Server to go ahead and be resource hog for my query?
I am only guessing, but I think it is using disk space to cache memory results. When I look at task manager memory utilization, I see SSMS at 161 MB. SSMS is where I am running the query from.
Here is my code - you don't have to read it in detail, but in brief, the source table contains about a million rows.
I need a solution, so alternative ideas are welcome...
WITH MetEdFliers AS
(
SELECT DISTINCT
[CustomerName1], [Mailing_Address], [Mailing_Address2], [Mailing_Zip]
FROM
[dbo].[_MetEd_Detail]
WHERE
RunId = (SELECT RunId FROM LastLoadRuns WHERE UtilityId = 9)
AND [Profitable] = 1 -- and not low income, should flag exist
),
MetEdLookUpFirst AS
(
-- same as [dbo].[VW_MetEd_Master_Profitable_ExcludeBadAddress]
SELECT
IIF (DET.IncalculableMailAddress = 1,
IIF (AA.Address1 IS NULL, 'Bad Address Undefined Fix -- Source Address Provided', 'Fixed Bad Source Address Via Lookup'), '') AS AddressStatus,
DET.ACCT_NO,
(CAST(DET.Monthly1 as Decimal) +
CAST(DET.Monthly2 as Decimal) +
CAST(DET.Monthly3 as Decimal) +
CAST(DET.Monthly4 as Decimal) +
CAST(DET.Monthly5 as Decimal) +
CAST(DET.Monthly6 as Decimal) +
CAST(DET.Monthly7 as Decimal) +
CAST(DET.Monthly8 as Decimal) +
CAST(DET.Monthly9 as Decimal) +
CAST(DET.Monthly10 as Decimal) +
CAST(DET.Monthly11 as Decimal) +
CAST(DET.Monthly12 as Decimal)) AS BilledKWHTotal,
DET.Polar, DET.CustomerName1,
REPLACE (IIF (DET.IncalculableMailAddress = 1,
IIF (AA.Address1 IS NULL, DET.Mailing_Address, AA.Address1), DET.Mailing_Address), ',', ';') AS Address1,
REPLACE (IIF (DET.IncalculableMailAddress = 1,
IIF (AA.Address2 IS NULL, DET.Mailing_Address2, AA.Address2), DET.Mailing_Address2), ',', ';') AS Address2,
REPLACE (IIF (DET.IncalculableMailAddress = 1,
IIF (AA.City IS NULL, DET.Mailing_City, AA.City), DET.Mailing_City), ',', ';') AS City,
IIF (DET.IncalculableMailAddress = 1,
IIF (AA.[State] IS NULL, DET.Mailing_State, AA.[State]), DET.Mailing_State) AS [State],
IIF (DET.IncalculableMailAddress = 1,
IIF (AA.Zip IS NULL, DET.Mailing_Zip, AA.Zip), DET.Mailing_Zip) AS ZIP,
IIF (DET.IncalculableMailAddress = 1, '', DET.Mailing_Zip4) AS ZIP4,
REPLACE (DET.Address, ',', ';') AS ServiceAddress,
REPLACE (DET.City, ',', ';') AS ServiceAddressCity,
DET.State ASs ServiceAddressState,
DET.Zip AS ServiceAddressZip,
DET.Zip4 AS ServiceAddressZip4,
DET.ProfitAnnualPotential AS [Potential Annual Profit]
FROM
_MetEd_DETAIL DET
LEFT JOIN
AccountAddress AA ON (DET.ACCT_NO = AA.ACCT_NO AND AA.UtilityId = 9)
WHERE
RunId = (SELECT RunId FROM LastLoadRuns WHERE UtilityId = 9)
AND DET.Profitable = 1 --AND det.CAP_CUSTOMER = 0
AND (DET.IncalculableMailAddress = 0 OR (AA.Address1 IS NOT NULL))
)
SELECT X.*
FROM MetEdFliers Fliers
OUTER APPLY
(SELECT TOP 1 *
FROM MetEdLookUpFirst LU
WHERE LU.CustomerName1 = Fliers.CustomerName1
AND LU.Address1 = Fliers.Mailing_Address
AND LU.Address2 = Fliers.Mailing_Address2
AND LU.Zip = Fliers.Mailing_Zip) X
It looks to be difficult.
I am going to handle it in my source program that generates input files for the sql server database ( i real the cvs into a table using import ).
To handle this problem, I am going to use a technology called dictionary, with key value pair, in c#.
I will be able to tell if the key had been added before, and if so, I replace the key value pair with the new key value pair and the annual profit potential field with the sum from both records....
Note: Prior method, I did not have sum (enhancement).

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)

Updating multiple columns in Oracle

If I try to add in (, CCY_TO_BASE_RATE = EXCHANGERATE.MID_RATE) into the update statement it shows the following errors.
ORA-06550: line 8, column 21:
PL/SQL: ORA-00923: FROM keyword not found where expected
ORA-06550: line 6, column 1:
PL/SQL: SQL Statement ignored
However, without that (, CCY_TO_BASE_RATE = EXCHANGERATE.MID_RATE), the statement is valid.
So how would I need to edit my codes so that the statement will be valid?
DECLARE
v_system_base_ccy NVARCHAR2(10);
BEGIN
v_system_base_ccy := dbo.Fn_parameter('SYSTEMBASECCY');
UPDATE tbl_dvcollateral A
SET coll_value_base = (SELECT coll_value * Nvl(EXCHANGERATE.mid_rate, 1),
ccy_to_base_rate = EXCHANGERATE.mid_rate
FROM (SELECT mid_rate,
from_ccy
FROM TABLE(
dbo.Fn_exchangeratetable(:V_AS_OF_DATE,
NULL,
v_system_base_ccy) )
)EXCHANGERATE
WHERE A.ccy = EXCHANGERATE.from_ccy(+)),
last_updated_by = :V_LOGIN_ID,
last_updated_datetime = To_timestamp(To_char(systimestamp,
'YYYY-MM-DD HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS')
WHERE as_of_date = :V_AS_OF_DATE
AND record_status_id = :V_AUTHORIZED;
END;
I may be misinterpreting what you're doing, but you seem to have the target column on the wrong side of the update statement:
UPDATE tbl_dvcollateral A
SET (coll_value_base, ccy_to_base_rate) =
(SELECT coll_value * Nvl(EXCHANGERATE.mid_rate, 1),
EXCHANGERATE.mid_rate
FROM (SELECT mid_rate,
...
In line 8 you have
ccy_to_base_rate = EXCHANGERATE.mid_rate
as a select-expression. This is technically a boolean which Oracle SQL does not tolerate.
You need to remove this expression. I cannot tell what you need to replace it with since I have no idea what you tried to formulate.

how Remove certain character at Front and back of a varchar

I have a customer data such as below
Table= Customer
field= CardNo
Data in CardNo:
%ABC?;9991?
%ABC?;99912?
%ABC?;999123?
%ABC?;888123?
Output i want is
9991
99912
999123
888123
However I want to remove all the "%ABC?;" at the front and "?" at the back, in the entire CardNo field. How I do it? I have tried this with no success:
UPDATE Customer
SET cardno = RIGHT(cardno, LEN(cardno) - 7)
I get an error:
"Return Error
Msg 536, Level 16, State 2, Line 1
Invalid length parameter passed to the RIGHT function.
The statement has been terminated."
What's wrong and how can I fix it?
Try like this...
UPDATE Table1 Set Cid=Replace(Left(Cid,Len(CID)-1),'%ABC?;','') FROM TABLE1
Sql Fiddle Demo
If you don't mean exactly this, you should probably be more clear what your intended result is:
DECLARE #foo VARCHAR(32)
SET #foo = '%ABC?;888123?'
SELECT SUBSTRING(#foo, 7, LEN(#foo) - 7)
Result: 888123
As applied to your code:
UPDATE Customer
SET cardno = SUBSTRING(cardno, 7, LEN(cardno) - 7)
Demo
REPLACE will work well. REPLACE('%ABC?;9991?', '%ABC?', '')
You can chain them together to remove the second ? as well.
Here is a rather brute force way, considering all possibilities for the pattern:
UPDATE Customer
SET cardno = (case when cardno like '[%]ABC[?];%[?]'
then substring(cardno, 6, len(cardno) - 7)
when cardno like '[%]ABC[?];%'
then substring(cardno, 6, len(cardno) - 6)
when cardno like '%[?]'
then substring(cardno, len(cardno) - 1)
else cardno
end)