Getting an error: Argument data type varchar is invalid for argument 2 of substring function - sql

I'm trying to get a substring from the value of a column and I'm getting the following error Argument data type varchar is invalid for argument 2 of substring function.
The column type is NvarChar(50) and is a system column for an application, so I can't modify it.
Ideally I'd just be able to select the substring as part of the query without having to alter the table, or create a view or another table.
Here's my query
SELECT SUBSTRING(INVOICE__, ':', 1)
FROM dwsystem.dbo.DWGroup
Im trying to select only everything in the string after a specific character. In this case the : character.

Use charindex with : as the first argument
select substring(invoice__,charindex(':',invoice__)+1,len(invoice__))
from dwsystem.dbo.dwgroup

SUBSTRING parameter is start position and end position so both parameter will be number like below
SELECT SUBSTRING(INVOICE__, 1, 1)
FROM dwsystem.dbo.DWGroup
you can use SUBSTRING_INDEX as you used mysql
SELECT SUBSTRING_INDEX(INVOICE__,':',-1);
example
SELECT SUBSTRING_INDEX('mytestpage:info',':',-1); it will return
info

Related

Cannot create a Computed column using RIGHT function because CHARINDEX returns null

So I have a Document table where I want to add a computed column named FileType using the column FileName. Below is the code I used to add a Computed Column:
ALTER TABLE dbo.Document
Add FileType AS UPPER(RIGHT(FileName,CHARINDEX('.',REVERSE(FileName))-1))
It turns out some of the data in FileName column does not have a '.' in their name which is causing the issue. I want to somehow implement a check to return CharIndex of only those data consisting of a '.' in their FileName. But I cannot write a Select statement in the Alter statement.
NOTE: I tried to find solution from following links which helped me find the issue but I could not derive any solution from them.
Error: invalid length parameter passed to the right function in name parsing script
Invalid length parameter passed to the RIGHT function
Invalid length parameter passed to the RIGHT function in update statement
Use a case expression to make it conditional e.g.
UPPER(RIGHT(FileName, case when CHARINDEX('.',REVERSE(FileName)) > 0 then CHARINDEX('.',REVERSE(FileName))-1 else len(Filename) end))
The simplest method is to add the delimiter:
UPPER(RIGHT(FileName, CHARINDEX('.', REVERSE(FileName) + '.') - 1))
No conditional logic is needed.

SQL Query to select a value between two known strings

I need a SQL query to get the value between two known strings in a text column.
The column name is d_info and the table name is Details.
The text is an XML fragment, but stored as a text value.
What I need is to get the value between the bookends <nettoeinkommen> and </nettoeinkommen> which is 718 in this example.
I also need the output to be saved in new column named income with data type float(8).
land>DE</land></wohnanschrift><taetigkeit>rentner</taetigkeit><dkbkundenstatus><bestandskunde>false</bestandskunde></dkbkundenstatus><haushaltsangaben><einnahmen><einkommen><nettoeinkommen>718</nettoeinkommen></einkommen><kindergeld>0</kindergeld><vermietungverpachtungnetto>0</vermietungverpachtungnetto><elterngeld>0</elterngeld><rentenunbefristet>0</rentenunbefristet><unselbststaendigetaetigkeit>740</unselbststaendigetaetigkeit><geringfuegigebeschaeftigung>0</geringfuegigebeschaeftigung></einnahmen><ausgaben><warmmiete>550</warmmiete><ratenimmobilienfinanzierung>0</ratenimmobilienfinanzierung>
I tried this code:
SELECT cast(SUBSTRING(d_info, CHARINDEX('<nettoeinkommen>', d_info)
, CHARINDEX('</nettoeinkommen>', d_info) - CHARINDEX('<nettoeinkommen>', d_info)) as float(8)) as income
from dbo.Details
But it's returning an Error converting data type varchar to real.
When I remove the cast function, the script works but it returns <nettoeinkommen>718 instead of only 718.
Thanks.
It is starting at the start of the tag not the end of it.
SELECT cast(
SUBSTRING(
d_info,
CHARINDEX('<nettoeinkommen>', d_info) + len('<nettoeinkommen>'),
CHARINDEX('</nettoeinkommen>', d_info) - (CHARINDEX('<nettoeinkommen>', d_info) + len('<nettoeinkommen>'))
) as float(8)) as income
from dbo.Details
you might even have these defined in variables:
SELECT cast(
SUBSTRING(
d_info,
CHARINDEX(#startTag, d_info) + len(#startTag),
CHARINDEX(#endTag, d_info) - (CHARINDEX(#startTag,d_info)+ len(#startTag))
) as float(8)) as income
from dbo.Details
I think the code is much easier to understand with the variables.
You need to add the length of your opening tag from the start index and subtract from the length of your substring statement:
SUBSTRING(d_info, CHARINDEX('<nettoeinkommen>', d_info)+16,
CHARINDEX('</nettoeinkommen>', d_info) - CHARINDEX('<nettoeinkommen>', d_info)-16)
As it seems, you are querieing plain xml data, for such purpose sql-server provides xquery functionality:
SELECT CAST(r.d_info AS XML).value('(/haushaltsangaben/einnahmen/einkommen/nettoeinkommen)[1]', 'decimal(19,2)')
FROM
(
SELECT '<taetigkeit>rentner</taetigkeit>
<dkbkundenstatus>
<bestandskunde>false</bestandskunde>
</dkbkundenstatus>
<haushaltsangaben>
<einnahmen>
<einkommen>
<nettoeinkommen>718</nettoeinkommen>
</einkommen>
</einnahmen>
</haushaltsangaben>' AS d_info
) AS r
If you intend to query more info from your source, you will end up with a bunch of stacked substring, patindex functions or even your own defined functions. This should be more readable and mantainable.
Using XQuery: https://learn.microsoft.com/en-us/sql/t-sql/xml/query-method-xml-data-type
As for your initial issue The SUBSTRING function in SQL returns the subset from a string starting from a given index for a specific length. For example SELECT SUBSTRING('whatever',5,4) returns 'ever'.
In case of CHARINDEX it gives the index for the first found match of a given pattern within a string. Example SELECT CHARINDEX('ever','whatever') should return 5, as 'ever' starts at the fifth position in 'whatever').
Now in your case you need to add the length of '<nettoeinkommen>' to the starting charindex and substract the length of '</nettoeinkommen>' from the length of the substring:
Also consider using decimal or numeric type instead of float, if you need to precise calculations: https://technet.microsoft.com/en-us/library/ms187912(v=sql.105).aspx

Translate function not returning relevant string in amazon redshift

I am trying to use a simple Translate function to replace "-" in a 23 digit string. The example of one such string is "1049477-1623095-2412303" The expected outcome of my query should be 104947716230952412303
The list of all "1049477-1623095-2412303" is present in a single column "table1". The name of the column is "data"
My query is
Select TRANSLATE(t.data, '-', '')
from table1 as t
However, it is returning 104947716230952000000 as the output.
At first, I thought it is an overflow error since the resulting integer is 20 digit so I also tried to use following
SELECT CAST(TRANSLATE(t.data,'-','') AS VARCHAR)
from table1 as t
but this is not working as well.
Please suggest a way so that I could have my desirable output
This is too long for a comment.
This code:
select translate('1049477-1623095-2412303', '-', '')
is going to return:
'104947716230952412303'
The return value is a string, not a number.
There is no way that it can return '104947716230952000000'. I could only imagine that happening if somehow the value is being converted to a numeric or bigint type.
Try regexp_replace()
Taking your own example, execute:
select regexp_replace('[string / column_name]','-');
It can be achieve RPAD try below code.
SELECT RPAD(TRANSLATE(CAST(t.data as VARCHAR),'-','') ,20,'00000000000000000000')

SQL: Invalid length parameter passed to the LEFT or SUBSTRING function

I am getting the following error while trying to execute the below query:
'Invalid length parameter passed to the LEFT or SUBSTRING function'
select A.NUMBER,
SUBSTRING(A.DESCRIPTION,
CHARINDEX(','+CAST(A.Description as VARCHAR(255)) + ',','from')+4,
CHARINDEX(','+CAST(A.Description as VARCHAR(255))+ ',','to')- 1)
from dbo.ACTIVITYM1 A
where A.DESCRIPTION like 'Reassignment from%'
Schema Details:
Activitym1 : Table Name
Description : Column
Number : Column.
Kindly let me know, what is the cause of this error.
A.Description contains something like below
"Reassignment from PSM_Support to PPM_Support"
I am trying to get PSM_Support in 1 column and PPm_Support in another column.
Here's your substring broken out:
SELECT SUBSTRING(
A.DESCRIPTION,
CHARINDEX(','+CAST(A.Description as VARCHAR(255))+',','from')+4, -- start
CHARINDEX(','+CAST(A.Description as VARCHAR(255))+ ',','to')- 1 -- length
)
I would check on the third parameter (length) by putting it into its own column. It must be > 0.
You have understood the syntax of CHARINDEX incorrectly. You have to search 'from' or 'to' in Description but not Description in 'from' or 'to'. I hope you understood the issue here. Just reverse them and you will get it correct.

Argument data type uniqueidentifier is invalid for argument 1 of substring function

I am trying to get the first part of a Guid Field with the TSQL substring function as follows
SELECT SUBSTRING(Guid, 1, 8) AS Gu FROM MyTable
but all i get is this error.
Argument data type uniqueidentifier is invalid for argument 1 of substring function.
So what is going on here? Should i treat the Guid as pure string first or...?
Thanks in advance!
Try this:
SELECT SUBSTRING(CAST(Guid AS varchar(38)), 1, 8) AS Gu FROM MyTable
You can't perform SUBSTRING directly on a uniqueidentifier; you need to cast it to a string type (varchar) first.