Substring length as variable in OpenSQL query? - abap

I want to select the length of the string ( LGOBE ) minus 4.
But i get this error:
"In the function "SUBSTRING", the parameter number "3" must be an ABAP variable.
This is not the case for the expression that starts with "LENGTH"."
What I understand from this message is that i cannot use a function as the third parameter, is this interpretation correct?
If so, is there an alternative for me to remove the last 4 places of the string inside the select statement? Thank you.
SELECT
SUBSTRING( LGOBE,1, LENGTH( LGOBE ) - 4 ) AS TEST1,
LGOBE, WERKS
FROM T001L INTO TABLE #DATA(IT_FINAL)
UP TO 100 ROWS.
CL_DEMO_OUTPUT=>DISPLAY( IT_FINAL ).

Checking the 754 documentation:
SUBSTRING( sql_exp,pos,len ) sql_exp: see below
pos: Literal, host variable, or host expression with the ABAP type b, s, i, int8
len: Literal or host constant with the ABAP type b, s, i, int8
Now 755:
SUBSTRING( sql_exp,pos,len )
Substring sql_exp from the position pos with length len. pos and len must be specified so that the substring is within sql_exp. sql_exp: see below
pos: SQL expression with the ABAP type b, s, i, int8
len: SQL expression with the ABAP type b, s, i, int8
Interestingly I cannot find that mentioned in the release notes itself.
So either you upgrade to 755 release or you'll have to do the processing in ABAP after selection.

Related

Function to get a Sub String after a selected character in place selectively and dynamically

In one of the database tables, I have a nvarchar type field that contains a series of special strings combined with some special characters. For example:
'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD'
or
'SJDGh-SUDYSUI-jhsdhsj-YTsagh-ytetyyuwte-sagd'
or
'hwerweyri~sdjhfkjhsdkjfhds~jsdfhjsdhf~mdnfsd,mfn'
Based on a formula, a sub string is always returned after the special character. But this string may be after the first, second or third place of the special character - or _ or ~. I used Charindex and Substring function in SQL server. But always only the first part of the character string after the selected character is returned. for example:
select SUBSTRING ('hwerweyri~sdjhfkjhsdkjfhds~jsdfhjsdhf~mdnfsd,mfn', 0, CHARINDEX('~', 'hwerweyri~sdjhfkjhsdkjfhds~jsdfhjsdhf~mdnfsd,mfn', 0))
returned value: hwerweyri
If there is a solution for this purpose or you have a piece of code that can work in solving this problem, please advise.
It is important to mention that the location of the special character must be entered by ourselves in the function, for example, after the third repetition or the second repetition or the tenth repetition. The method or code should be such that the location can be entered dynamically and the function does not need to be defined statically.
For Example:
'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD' ==> 3rd substring ==> 'GFSDGFSHDGF'
'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD' ==> second substring ==> 'HGSDHGJD'
'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD' ==> 1st substring ==> 'JHJSD'
And The formula will be sent to the function through a programmed form and the generated numbers will be numbers between 1 and 15. These numbers are actually the production efficiency of a product whose form is designed in C# programming language. These numbers sent to the function are variable and each time these numbers may be sent to the function and applied to the desired character string. The output should look something like the one above. I don't know if I managed to get my point across or if I managed to make my request correctly or not.
Try the following function:
CREATE FUNCTION [dbo].[SplitWithCte]
(
#String NVARCHAR(4000),
#Delimiter NCHAR(1),
#PlaceOfDelimiter int
)
RETURNS Table
AS
RETURN
(
WITH SplitedStrings(Ends,Endsp)
AS (
SELECT 0 AS Ends, CHARINDEX(#Delimiter,#String) AS Endsp
UNION ALL
SELECT Endsp+1, CHARINDEX(#Delimiter,#String,Endsp+1)
FROM SplitedStrings
WHERE Endsp > 0
)
SELECT f.DataStr
FROM (
SELECT 'RowId' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'DataStr' = SUBSTRING(#String,Ends,COALESCE(NULLIF(Endsp,0),LEN(#String)+1)-Ends)
FROM SplitedStrings
) f WHERE f.RowId = #PlaceOfDelimiter + 1
)
How to use:
select * from [dbo].[SplitWithCte](N'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD', N'_', 3)
or
select DataStr from [dbo].[SplitWithCte](N'HGHGSD_JHJSD_HGSDHGJD_GFSDGFSHDGF_GFSD', N'_', 3)
Result: GFSDGFSHDGF

Error converting VarChar to VarBinary in SQL Server

I need to convert varchar to varbinary. The query I'm using is working correctly for only some values.
This one is working fine
SELECT CONVERT (VARBINARY(MAX), 'AFE27AF97DC6', 2)
while this one throws an error
Error converting data type varchar to varbinary
SELECT CONVERT (VARBINARY(MAX), 'AFEE27AF97DC6', 2)
I need to use style 2.
I've read all the similar questions but I couldn't find the solution. Any thought would help me. Thank you!
Hmm, AFEE27AF97DC6 is one nibble short and it seems like only full bytes are accepted. Try to zero pad it. E.g.
SELECT convert(varbinary(max), '0AFEE27AF97DC6', 2)
You can also wrap it in a CASE expression checking if the string has an even or odd length, should the strings be variable.
SELECT convert(varbinary(max),
CASE
WHEN len('AFEE27AF97DC6') % 2 <> 0 THEN
concat('0', 'AFEE27AF97DC6')
ELSE
'AFEE27AF97DC6'
END,
2)
(Replace the literals with your variable.)
This is pretty clearly stated in the documentation:
1, 2 [for the third argument]
For a binary data_type, the expression must be a character expression. The expression must have an even number of hexadecimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, a, b, c, d, e, f).
Your first string has a length of 12, so it converts fine. The second has a length of 13, so it is not valid.
I am not sure what you intend, but a 0 in the 3rd position gives similar results for the two conversions:
SELECT CONVERT(varbinary(max),'AFE27AF97DC6' , 2), CONVERT(varbinary(max),'AF0EE27AF97DC6' , 2)
Gives:
0xAFE27AF97DC6 0xAF0EE27AF97DC6

Why does this query return a money value?

Today I wrote a query that should return an error. Instead, it returns the value 15 with column name why and data type money.
Do you have an idea why?
select \15why
Result:
why
15.00
You're specifying a constant:
money constants are represented as string of numbers with an optional decimal point and an optional currency symbol as a prefix
So select €15 results in a money constant, and so does select $15, as well as select ¥15.
There's a peculiarity as pointed out by Jeroen in the comments:
Because the yen sign (¥) is a currency indicator, and in some native Japanese character sets, its code point is the same as the one for backslash in ASCII.
See also MSDN: money and smallmoney (Transact-SQL).
So select \15 appears to be equal to select ¥15.
As for the column name: select 5a results in a column with the alias a and a value of 5. Because "a" is not a numeric suffix, it is treated as select 5 as a, where "as" is optional. Instead select 5e would return 5 in an unnamed column, because "e" is a numeric suffix.
So you've discovered a different way to write select ¥15 as why.

Using SUBSTRING with a column name

I've been trying this all morning and can't find what I'm doing wrong. I have a string, 'XXYY0000' and I need the XX and YY seperatly.
So this works and gets the XX values:
SELECT LEFT(l.LOAN_MATURITY, 2)
FROM LOAN As l
But why is this not working when I need to get the YY values?
SELECT SUBSTRING(l.LOAN_MATURITY, 3, 2)
FROM LOAN As l
I researched and it should give the same output as the MID() function, but it gives me this error.
Msg 8116, Level 16, State 1, Line 1
Argument data type numeric is invalid for argument 1 of substring function.
Why is the data type important for the SUBSTRING function but not the LEFT function?
LEFT:
LEFT ( character_expression , integer_expression )
character_expression
Is an expression of character or binary data. character_expression can be a constant, variable, or column. character_expression can be of
any data type, except text or ntext, that can be implicitly converted
to varchar or nvarchar. Otherwise, use the CAST function to explicitly
convert character_expression.
SUBSTRING:
SUBSTRING ( expression ,start , length )
expression
Is a character, binary, text, ntext, or image expression.
With LEFT there is implicit CAST, with SUBSTRING not. You need to CAST it manually:
SELECT SUBSTRING(CAST(l.LOAN_MATURITY AS VARCHAR(100)), 3, 2)
FROM LOAN As l

How to set a string value into varbinary

I'm using SQL Server and I'm trying to set a string into a varbinary without converting its value.
Example:
declare #string varchar(max)
set #string='0x7777'
update tablename
set Data=#string
I know this is not possible since it's not allowed. However I don't wanna convert the string to varbinary (using select CONVERT(varbinary(max),#string)) since it'll result in saving:
0x307837373737
Also, I know that making #string varbinary and removing ' 's would fix the problem, however that's not what I'm looking for since I'm working with strings in order to save it inside a varbinary.
I want the output to be: 0x7777 inside the varbinary
Thank you.
You can use CONVERT, just pass 3rd parameter.
update tablename
set Data=convert(varbinary(max), #string, 1)
If the data_type is a binary type, the expression must be a character
expression. The expression must be composed of an even number of
hexadecimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, a,
b, c, d, e, f). If the style is set to 1 the characters 0x must be the
first two characters in the expression. If the expression contains an
odd number of characters or if any of the characters are invalid an
error is raised.
See reference for binary styles conversion.